Claw Doctor — Habilidade de Auto-Reparo do OpenClaw

Diagnostica e corrige problemas comuns do OpenClaw/NanoClaw — habilidades quebradas, scripts ausentes, falhas de chave de API, bugs de resolução de caminho e problemas de configuração. A meta-habilidade para quando sua garra está quebrada.

O que é Claw Doctor — Habilidade de Auto-Reparo do OpenClaw?

Esta meta-habilidade (skill) foi projetada para diagnosticar e reparar problemas comuns encontrados em agentes OpenClaw/NanoClaw. Ela abrange falhas de carregamento de habilidades, scripts ausentes (erro 'No such file or directory'), chaves de API não configuradas, dependências faltando (Node.js, Python, etc.), erros de frontmatter YAML, e regressões pós-atualização. Inclui procedimentos avançados para ambientes de produção, como limpeza de sessões com override de modelo que causam variação de comportamento entre agentes, correção de jobs cron que roteiam incorretamente para OpenRouter, e resolução de conflitos entre versões do gateway, como o erro 'device signature invalid'. A habilidade é compatível com Claude Code, Cursor e outros agentes que suportam skills MD. Ela funciona fornecendo comandos de diagnóstico e correção para cada problema catalogado, desde verificações rápidas de ambiente até manipulações de arquivos de configuração JSON. O objetivo é permitir que o próprio agente ou o usuário resolva problemas sem intervenção manual externa, acelerando o ciclo de debugging.

Funciona com✓Claude Code~Codex CLI~Cursor✓Gemini CLI
npx skills add tianyilt/openclaw-repair-skills

Installed? Explore more Programação e Desenvolvimento skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

Perguntar na sua IA favorita

Abre um novo chat com esta habilidade de agente já pré-carregada.

Documentação

O que Claw Doctor — Habilidade de Auto-Reparo do OpenClaw faz?

Esta habilidade diagnostica e corrige problemas comuns do OpenClaw/NanoClaw. Quando algo quebrar, percorra a lista de verificação abaixo antes de desistir.


Quando Ativar

Ative esta habilidade quando o usuário relatar qualquer um dos seguintes:

  • "skill not found" / habilidade não dispara
  • "No such file or directory" ao executar um script de habilidade
  • Erros de chave de API vindos de uma habilidade
  • Habilidade não produz saída ou produz saída incorreta
  • "SKILL.md is invalid" / erros de parse YAML
  • Uma habilidade funciona globalmente, mas não no workspace (ou vice-versa)
  • Habilidades funcionavam antes, mas pararam após uma atualização

Ordem de Carregamento e Caminhos

O OpenClaw carrega habilidades de dois locais. Habilidades do workspace têm prioridade.

Priority 1 (high): <workspace>/skills/<skill-name>/SKILL.md
Priority 2 (low):  ~/.openclaw/skills/<skill-name>/SKILL.md

Diagnóstico: liste todas as habilidades carregadas

# Mostra o que está instalado globalmente
ls ~/.openclaw/skills/ 2>/dev/null || echo "No global skills dir"

# Mostra o que está instalado no workspace atual
ls ./skills/ 2>/dev/null || echo "No workspace skills dir"

Se uma habilidade aparecer em ambos, a versão do workspace vence — verifique se há incompatibilidades de versão.


Problema 1 — Habilidade Não Dispara

Sintoma: O usuário invoca uma habilidade, mas o Claude a ignora ou não segue o procedimento.

Lista de verificação de diagnóstico:

  1. O arquivo SKILL.md está realmente presente e legível?

    cat ./skills/<skill-name>/SKILL.md | head -20
    
  2. O frontmatter YAML é analisado corretamente?

    python3 -c "
    import re, sys
    txt = open('skills/<skill-name>/SKILL.md').read()
    fm = re.search(r'^---\n(.*?)\n---', txt, re.DOTALL)
    print('Frontmatter found:', bool(fm))
    if fm:
        import yaml; d = yaml.safe_load(fm.group(1)); print('Keys:', list(d.keys()))
    "
    
  3. As keywords no SKILL.md correspondem ao que o usuário disse?

    • Adicione mais variantes de palavras-chave (sinônimos, abreviações) se não estiverem correspondendo.
  4. A description é clara o suficiente para o modelo identificar a habilidade?

    • Descrições curtas e específicas superam as vagas.

Correção: Garanta que o frontmatter seja YAML válido (sem tabs, aspas adequadas, indentação correta).


Problema 2 — Script Não Encontrado (Resolução de Caminho)

Sintoma: bash: scripts/run: No such file or directory

Este é o bug de habilidade mais comum. Scripts referenciados no SKILL.md como scripts/foo são relativos ao diretório de instalação da habilidade dentro do cache de plugins do OpenClaw, não ao diretório de trabalho atual.

Correção canônica — resolva o caminho do script dinamicamente antes de cada uso:

# Para uma habilidade chamada "my-skill" com um script chamado "run"
MY_SCRIPT=$(find ~/.openclaw -name "run" -path "*/my-skill/*/scripts/*" -type f 2>/dev/null | head -1)
# Fallback: verifique as habilidades do workspace
[ -z "$MY_SCRIPT" ] && MY_SCRIPT=$(find ./skills -name "run" -path "*/my-skill/scripts/*" -type f 2>/dev/null | head -1)

if [ -z "$MY_SCRIPT" ]; then
  echo "ERROR: script not found. Is the skill installed?"
  exit 1
fi

$MY_SCRIPT <args>

Verifique também: O script é executável?

chmod +x ~/.openclaw/skills/my-skill/scripts/*
chmod +x ./skills/my-skill/scripts/*

Problema 3 — Chave de API Não Configurada

Sintoma: Habilidade retorna {"success": false, "setup_required": true} ou erros 401/403.

Fluxo padrão de configuração de chave de API:

  1. O SKILL.md da habilidade deve documentar onde a chave é armazenada (geralmente ~/.openclaw/secrets/<skill-name>.key ou uma variável de ambiente).
  2. Verifique se o arquivo de chave existe:
    ls ~/.openclaw/secrets/ 2>/dev/null || echo "No secrets dir"
    
  3. Execute o comando de configuração da habilidade (geralmente scripts/run setup <api-key>).
  4. Verifique se a chave foi salva:
    cat ~/.openclaw/secrets/<skill-name>.key 2>/dev/null | head -c 20
    

Se não houver comando de configuração, peça ao usuário para definir a variável de ambiente diretamente:

export SKILL_API_KEY="their-key-here"
# Adicione ao ~/.zshrc ou ~/.bashrc para persistência

Problema 4 — Dependência Ausente (Node.js / Python / ferramenta)

Sintoma: node: command not found, python3: No such file or directory, jq: command not found

Verificação rápida de dependências:

echo "=== Core deps ===" && \
node --version 2>/dev/null || echo "MISSING: node" && \
python3 --version 2>/dev/null || echo "MISSING: python3" && \
jq --version 2>/dev/null || echo "MISSING: jq" && \
curl --version 2>/dev/null | head -1 || echo "MISSING: curl"

Correção por plataforma:

FerramentamacOSUbuntu/Debian
Node.jsbrew install nodeapt install nodejs npm
Python 3brew install python3apt install python3
jqbrew install jqapt install jq

Para dependências Python da habilidade:

pip3 install -r skills/<skill-name>/requirements.txt 2>/dev/null \
  || echo "No requirements.txt found"

Para dependências Node da habilidade:

cd skills/<skill-name> && npm install 2>/dev/null \
  || echo "No package.json found"

Problema 5 — Erros no Frontmatter YAML

Sintoma: Habilidade carrega, mas os metadados estão errados / palavras-chave não indexadas.

Template de frontmatter válido:

---
name: my-skill-name         # minúsculas, apenas hífens
description: Uma frase clara descrevendo o que esta habilidade faz.
keywords:
  - keyword-one
  - keyword-two
license: MIT
---

Erros comuns:

ErroCorreção
Tabs em vez de espaçosSubstitua por indentação de 2 espaços
: sem aspas na descriçãoColoque o valor entre aspas
Campo name ausenteAdicione-o — é obrigatório
keywords como lista inline [a, b]Use lista de blocos - a\n- b

Validar:

python3 -c "
import yaml, sys
txt = open('skills/<skill-name>/SKILL.md').read().split('---')[1]
try:
    d = yaml.safe_load(txt)
    print('OK:', d)
except yaml.YAMLError as e:
    print('YAML ERROR:', e)
    sys.exit(1)
"

Problema 6 — Habilidade Funcionava Antes, Quebrou Após Atualização

Sintoma: O OpenClaw foi atualizado e uma habilidade parou de funcionar.

Lista de verificação:

  1. Verifique se o cache de plugins do OpenClaw foi limpo:

    ls ~/.openclaw/plugins/cache/ 2>/dev/null | head -10
    
  2. Reinstale a habilidade a partir da fonte:

    # De um repositório de habilidades clonado
    cp -r /path/to/skills-repo/skills/<skill-name> ~/.openclaw/skills/
    
  3. Verifique se há mudanças disruptivas na API de habilidades do OpenClaw — consulte o changelog do OpenClaw para atualizações do formato SKILL.md.

  4. Teste o script diretamente (ignorando o OpenClaw):

    bash skills/<skill-name>/scripts/<main-script> --help
    

Verificação Completa de Saúde

Execute isto para obter um instantâneo completo do ambiente OpenClaw:

echo "=== OpenClaw Health Check ===" && \
echo "--- Global skills ---" && ls ~/.openclaw/skills/ 2>/dev/null || echo "(none)" && \
echo "--- Workspace skills ---" && ls ./skills/ 2>/dev/null || echo "(none)" && \
echo "--- Secrets ---" && ls ~/.openclaw/secrets/ 2>/dev/null || echo "(none)" && \
echo "--- Plugin cache ---" && ls ~/.openclaw/plugins/cache/ 2>/dev/null | head -5 || echo "(empty)" && \
echo "--- Dependencies ---" && \
  node --version 2>/dev/null && \
  python3 --version 2>/dev/null && \
  jq --version 2>/dev/null && \
echo "=== Done ==="

Para Usuários do Claude Code

Esta habilidade também funciona como uma habilidade invocável pelo usuário no Claude Code. Adicione o seguinte a ~/.claude/CLAUDE.md sob ## User-Invocable Skills:

### claw-doctor

Diagnostica e corrige problemas do OpenClaw / NanoClaw.

**Trigger**: usuário menciona habilidade não carregando, script não encontrado, erro de chave de API, SKILL.md quebrado, OpenClaw não funcionando

**Procedimento**: Siga a lista de verificação do claw-doctor SKILL.md:
1. Identifique a categoria do sintoma (disparo / caminho do script / chave de API / dependência / YAML / pós-atualização)
2. Execute os comandos de diagnóstico relevantes
3. Aplique a correção e verifique com a Verificação Completa de Saúde

Problema 7 — Bot do Feishu Usando o Modelo Errado

Sintoma: O modelo respondido no Feishu não corresponde ao configurado em openclaw.json, ou após /new ainda é o modelo antigo.

Causa Raiz 1 — O model override na sessão sobrescreve a configuração do agente

O arquivo de sessão persiste a última troca manual de modelo e não é limpo ao reiniciar.

# Descubra qual sessão tem model override
python3 -c "
import json
for agent in ['main', 'sii']:
    path = f'/Users/tianyiliang/.openclaw/agents/{agent}/sessions/sessions.json'  # ajuste o caminho conforme necessário
    try:
        data = json.load(open(path))
        for k, v in data.items():
            if v.get('model'):
                print(f'[{agent}] {k}: model={v[\"model\"]}')
    except: pass
"

Correção: Remova o campo model/modelProvider da sessão correspondente, ou exclua toda a entrada da sessão e reinicie o gateway:

openclaw gateway restart

Causa Raiz 2 — O agente main não está em agents.list, o binding é ignorado

O bindings tem "agentId": "main" mas não funciona — porque main é um agente interno e não está em agents.list como alvo de roteamento.

Diagnóstico:

openclaw agents list --bindings   # veja se main aparece

Correção: Adicione main explicitamente a agents.list:

python3 -c "
import json
import os
path = os.path.expanduser('~/.openclaw/openclaw.json')  # ajuste o caminho conforme necessário
cfg = json.load(open(path))
if not any(a['id'] == 'main' for a in cfg.get('agents', {}).get('list', [])):
    cfg.setdefault('agents', {}).setdefault('list', []).insert(0, {
        'id': 'main',
        'name': 'main',
        'workspace': cfg.get('agents', {}).get('defaults', {}).get('workspace', ''),
        'model': {'primary': 'custom-local/gemini-3-pro-preview', 'fallbacks': []}
    })
    json.dump(cfg, open(path,'w'), indent=2, ensure_ascii=False)
    print('Added main to agents.list')
"

Causa Raiz 3 — O ID do modelo não corresponde ao proxy local, causando fallback

O model ID configurado em openclaw.json não existe no proxy localhost, causando fallback silencioso para o próximo.

# Verifique os modelos realmente disponíveis
curl -s http://localhost:8317/v1/models -H "Authorization: Bearer your-api-key-1" \
  | python3 -c "import json,sys; [print(m['id']) for m in json.load(sys.stdin)['data']]" | sort

Compare com o model ID em openclaw.json e garanta correspondência exata.


Problema 8 — Cron Jobs Indo pelo OpenRouter

Sintoma: Em openclaw status, a sessão cron mostra model=openrouter/auto, não deveria ir para a nuvem.

Causa Raiz: A sessão tem authProfileOverride: openrouter:* persistido (resquício de uma troca automática de autenticação).

Diagnóstico:

python3 -c "
import json
import os
for agent in ['main', 'sii']:
    path = os.path.expanduser(f'~/.openclaw/agents/{agent}/sessions/sessions.json')
    try:
        data = json.load(open(path))
        for k, v in data.items():
            if 'cron' in k and 'openrouter' in v.get('authProfileOverride',''):
                print(f'[{agent}] {k}: auth={v[\"authProfileOverride\"]} model={v.get(\"model\")}')
    except: pass
"

Correção: Limpe todos os overrides do OpenRouter nas sessões cron:

python3 -c "
import json, glob
import os
for path in glob.glob(os.path.expanduser('~/.openclaw/agents/*/sessions/sessions.json')):
    data = json.load(open(path))
    changed = False
    for k, v in data.items():
        if 'cron' in k and 'openrouter' in v.get('authProfileOverride',''):
            for field in ['model','modelProvider','authProfileOverride','authProfileOverrideSource','authProfileOverrideCompactionCount']:
                v.pop(field, None)
            changed = True
            print(f'Fixed: {k}')
    if changed:
        json.dump(data, open(path,'w'), ensure_ascii=False)
" && openclaw gateway restart

Problema 9 — Gateway Sem Resposta / device signature invalid

Sintoma: openclaw status reporta RPC probe: failed, erro gateway closed (1008): device signature invalid. Bot do Feishu não responde, gateway parece estar rodando, mas o CLI não consegue conectar.

Causa Raiz: Após atualizar a versão do OpenClaw, o LaunchAgent antigo (com.clawdbot.gateway, carregando openclaw-cn) não foi removido e registra inicialização junto com o novo ai.openclaw.gateway. O processo antigo ocupa a porta 18789 primeiro, e o novo CLI é rejeitado devido à incompatibilidade no formato do device signature.

Diagnóstico:

launchctl list | grep -i claw
# Se aparecerem tanto com.clawdbot.gateway quanto ai.openclaw.gateway, este é o problema

openclaw gateway status 2>&1 | grep -E "RPC|device|pid"

Correção:

# 1. Faça backup e desabilite o LaunchAgent antigo
cp ~/Library/LaunchAgents/com.clawdbot.gateway.plist \
   ~/Library/LaunchAgents/com.clawdbot.gateway.plist.bak
launchctl bootout gui/$UID/com.clawdbot.gateway
mv ~/Library/LaunchAgents/com.clawdbot.gateway.plist \
   ~/Library/LaunchAgents/com.clawdbot.gateway.plist.disabled

# 2. Reinicie o novo gateway
openclaw gateway restart

# Verifique
openclaw gateway status 2>&1 | grep "RPC probe"
# Saída esperada: RPC probe: ok

Explicação: O arquivo .plist.disabled não é carregado pelo launchd na inicialização (que só reconhece extensão .plist), efetivamente desabilitando-o, mas mantendo um backup.


Problema 10 — Usuário Não Owner Bloqueado (Autorização OAuth / Chamada de Ferramenta)

Sintoma: Usuários do Feishu que não são o Owner do aplicativo enviam mensagens e a entrada de autorização ou chamada de ferramenta é rejeitada, com logs mostrando OwnerAccessDeniedError ou Permission denied: Only the app owner is authorized.

Causa Raiz: assertOwnerAccessStrict tem como padrão ownerOnly=true, rejeitando todos os usuários não Owner. Este é um problema conhecido do openclaw-lark upstream (issues #5, #12).

Solução A — Desligar via Configuração (Recomendado): Adicione uat.ownerOnly: false no canal Feishu em openclaw.json:

# Use python3 para escrita segura, evitando erros de edição manual de JSON
python3 - <<'EOF'
import json
import os

path = os.path.expanduser('~/.openclaw/openclaw.json')  # ajuste o caminho conforme necessário
cfg = json.load(open(path))
ch = cfg.setdefault('channels', {}).setdefault('feishu', {})
uat = ch.setdefault('uat', {})
uat['enabled'] = True
uat['ownerOnly'] = False
json.dump(cfg, open(path, 'w'), indent=2, ensure_ascii=False)
print('Done. Run: openclaw gateway restart')
EOF

Solução B — Atualizar o Plugin: Se você usa a versão plugin do código fonte do workspace (openclaw-lark), este patch já está incluído no PR #11:

  • src/core/config-schema.ts: UATConfigSchema adiciona ownerOnly?: boolean
  • src/core/owner-policy.ts: assertOwnerAccessStrict verifica a flag ownerOnly

Verificação: Após reiniciar o gateway, usuários não Owner devem conseguir enviar mensagens sem que o log exiba OwnerAccessDeniedError.


Contribuindo

Encontrou um novo modo de falha do OpenClaw? Abra um PR com:

  1. O sintoma (mensagem de erro exata ou comportamento)
  2. Causa raiz
  3. Comando de diagnóstico
  4. Correção

Mantenha as entradas curtas e priorize comandos. O médico deve ser rápido de consultar.

Habilidades Relacionadas