Solução de problemas
As coisas que de fato dão errado, o que a mensagem significa e o que fazer a respeito.
Comece por aqui, sempre
handbook config --command <the-command-that-failed>Ele imprime o ambiente ativo, cada arquivo .env carregado, o arquivo de configuração
resolvido e uma linha por opção com de onde veio o valor dela. A maioria dos problemas
de "ele ignorou a minha configuração" é respondida por essa tabela em dez segundos.
Configuração
source is required: pass --source, set HANDBOOK_GENERATE_SOURCE, or add it to handbook.config.yaml
Exatamente o que está escrito — e ele lista todas as formas de fornecer o valor. A obrigatoriedade é verificada depois que todas as camadas foram consultadas, então isso significa que nenhuma delas tinha o valor.
Minha variável de ambiente está sendo ignorada
handbook config --command generate | grep -i <setting>A coluna FROM diz qual camada realmente venceu. Causas de sempre:
- Uma flag está sobrepondo o valor. Flags ganham de tudo.
- Você definiu o nome plano, mas existe um com escopo —
HANDBOOK_GENERATE_DETAILganha deHANDBOOK_DETAIL. - Você definiu um valor vazio. Vazio é lido como não definido, deliberadamente.
- Você está executando de outro diretório: a cascata de
.envé só do cwd, ao contrário dohandbook.config.yaml, que é descoberto subindo pela árvore.
llmApiKey must not appear in a config file (it gets committed)
Mova-a para o .env ou para o ambiente do shell. Essa recusa é deliberada.
node: /some/path.env: not found, e código de saída 9
Não é um erro do Handbooks, de forma alguma. O Node >= 20.6 tem a sua própria flag
--env-file e pré-varre a linha de comando inteira procurando por ela, então morre com um
caminho inexistente antes de o Handbooks começar. Use a variável no lugar, que nada
consegue interceptar:
HANDBOOK_ENV_FILE=/some/path.env handbook config
# handbook: error: ENOENT: no such file or directory, open '/some/path.env'A flag funciona bem sempre que o arquivo realmente existir.
handbook.config.yaml: must contain a mapping of settings, not a list or a scalar
O arquivo foi lido como YAML, mas não é um objeto no nível superior. Verifique a indentação da primeira chave.
Análise
no analyzable files found under <dir>
O --source aponta para algum lugar sem nada que o analisador reconheça. Procure um erro
de digitação e confira se você está apontando para a raiz do código, e não para um
diretório de saída de build.
handbook analyze --source $REPO --work $WORK -v # see the per-language scanA contagem de arquivos está muito abaixo do esperado
Rode com -v e leia as linhas [scan]. Causas prováveis:
- Uma linguagem inteira está faltando na lista → veja Suporte a linguagens.
- Seu código está sob um diretório da lista compartilhada de exclusões (
vendor,build,dist,out,target, …). Aponte o--sourcepara a raiz real do código. - Swift no Node ≥ 24 → o adaptador recusou já na descoberta. Use
node --liftoff-only.
A contagem de arquivos está muito acima do esperado
Você está varrendo node_modules, uma árvore vendorizada ou código gerado. Os diretórios
comuns são pulados automaticamente; qualquer outro caso pede um --source mais estreito.
edgesDropped está enorme
Normal para linguagens dinâmicas, e não é um erro — cada chamada descartada é
categorizada em phase1/dropped-calls.json em vez de ser adivinhada:
jq '.metadata.byCategory' work/api/phase1/dropped-calls.jsonLinguagens de fidelidade genérica descartam mais, por design. Veja Fidelidade da análise.
Um arquivo que eu sei que existe não tem página no handbook
Pergunte primeiro à Phase 1 — um arquivo que nunca virou fato nunca vira página:
jq '.metadata.byReason' work/api/phase1/scan-coverage.json
jq -r '.files[] | "\(.reason)\t\(.file)\t\(.detail)"' work/api/phase1/scan-coverage.jsonreason | O que significa | O que fazer |
|---|---|---|
unreadable | a leitura falhou — permissões, symlink quebrado, uma corrida | conserte o arquivo ou o modo e rode analyze de novo |
unparsable | a gramática lançou erro ou não devolveu árvore | em geral shell + case; veja Suporte a linguagens |
partial | parseou, mas com erros de sintaxe | a página existe, porém incompleta — leia o próprio arquivo |
Os arquivos unreadable e unparsable são removidos de propósito do scannedFiles do
graph.json, para que nenhuma ficha seja escrita sobre um arquivo que o parser nunca leu
e para que o _coverage.json não possa contá-lo como descrito. Os arquivos partial
mantêm sua página: os fatos que estão nela são reais, só não são todos.
Um array files vazio significa que tudo parseou. Se o artefato não existe de todo, o
diretório de trabalho é anterior a esse registro — rode analyze de novo.
O Swift derruba o processo
Fatal process out of memory: ZoneA gramática de Swift incluída aborta no V8 ≥ 13. O adaptador recusa já na descoberta em um runtime desses, em vez de deixar isso acontecer — se você está vendo o abort em si, então está em um caminho de código que passou por cima disso. Rode com:
node --liftoff-only $(which handbook) analyze --source $REPO --work $WORKGeração
phases 2/3 need an LLM client (set OPENAI_API_KEY or pass --phase 1)
Nenhuma chave de API foi resolvida. Verifique handbook config --command generate — a
linha de llmApiKey vai dizer — unset (required). Para um endpoint local sem chave,
defina OPENAI_API_KEY=EMPTY explicitamente.
O endpoint retorna HTML
the endpoint returned an HTML page rather than JSON — this is usually a proxy or gateway login pageUm proxy corporativo está interceptando a requisição e devolvendo uma página de login com
200. Conserte o proxy, ou aponte o --base-url para algo alcançável.
As fichas voltam vazias
Veja o que o modelo de fato respondeu:
ls work/api/phase2/cards/_rejected/
cat work/api/phase2/cards/_rejected/*.txt | head -50Essas são as respostas que não produziram nenhuma ficha aproveitável. Causas comuns: um
modelo pequeno demais para seguir o schema, uma recusa ou truncamento. Tente
--detail brief, um --read-batch-size menor ou um --model mais forte.
Quais arquivos acabaram sem prosa:
jq '.missing' work/api/phase2/cards/_coverage.jsonErros de rate limit, ou uma execução muito lenta
Baixe o --llm-concurrency primeiro. Insistir com mais retentativas contra um rate
limit gasta os mesmos tokens duas vezes.
handbook generate --source $REPO --work $WORK \
--llm-concurrency 4 --llm-retries 8 --llm-retry-backoff 5As etapas não fazem sentido
handbook generate --source $REPO --work $WORK --phase 2b,2c,3 --synth-mode doctorO laço ator–crítico existe exatamente para isso. Se ainda assim falhar, escreva você mesmo
um skeleton.yaml e passe --skeleton.
work dir was generated with strategy "member" but --strategy file was given
Deliberado. Reexecute a Phase 2b para trocar de estratégia:
handbook generate --source $REPO --work $WORK --strategy file --phase 2b,2c,3another handbook run is already using <work>
Um lock. Ou há de fato uma execução em andamento — inclusive um job do Studio — ou uma execução anterior morreu de forma abrupta. Espere, ou remova o diretório de lock nomeado na mensagem depois de confirmar que nada está rodando.
Renderização e empacotamento
<dir> is not a rendered handbook (missing index.md)
O --handbook precisa apontar para o diretório renderizado (<work>/handbook), não
para o diretório de trabalho.
outDir must not be the handbook directory or an ancestor of it
A construção do skill começa apagando o --out. Apontá-lo para o handbook apagaria a
entrada. Use um diretório separado: --handbook work/api/handbook --out skills/api.
O validate avisa sobre hashes obsoletos
Funcionando como esperado: o código mudou desde o empacotamento. Avance o handbook:
handbook resync --case cases/latest --work work/api
handbook skill --handbook work/api/handbook --out skills/api --name api \
--work work/api --source $REPO --agent-dir work/api/handbook/agentPlanejamento e aplicação
planner produced no usable plan (fabrication) after N turn(s)
O modelo inventou seções ## Tool result — ele estava raciocinando sobre conteúdos de
arquivo imaginados. Nada dessa execução é confiável. Use um modelo mais forte.
planner reached the turn limit without producing a plan
Aumente o --max-turns, ou estreite o pedido. Um pedido vago faz o planejador explorar em
vez de localizar.
O apply diz no-match
O código mudou depois que o plano foi escrito. Reexecute o plan. Não edite a âncora à
mão para fazê-la casar — a âncora é o mecanismo de segurança.
O apply diz ambiguous
O texto de old aparece mais de uma vez. Reexecute o plan, ou edite o plano à mão para
incluir mais contexto ao redor em old, de modo que ele fique único.
EDIT 1: content between the fenced blocks
O conteúdo de old ou de new contém uma cerca de código que fechou o bloco cedo demais.
Abra esses blocos com uma cerca mais longa:
### EDIT 1
- file: `README.md`
````old
```bash
echo hi
```
````
````new
```bash
echo hello
```
````O rollback recusa um arquivo
O hash atual dele não bate com o hash pós-patch — alguém o editou depois do patch, e
restaurar destruiria esse trabalho. Veja o que mudou e então use --force, se tiver
certeza.
Studio
403 ao abrir o Studio
Você não está usando localhost. A proteção contra CSRF verifica o cabeçalho Host, então
um IP da LAN ou um nome de contêiner é recusado por design. Use
http://localhost:4860, ou um túnel SSH:
ssh -L 4860:localhost:4860 user@hostrepo "x" already has a running job
Um job por repositório de cada vez, porque os artefatos não são seguros para escritores concorrentes. Espere, ou cancele o job em execução pela interface.
Ainda travado
handbook <command> -v # debug logging
handbook config --command <cmd> --json # full resolved configuration
cat work/api/run-manifest.json # what the last good run did
ls work/api/phase2/cards/_rejected/ # what the model actually replied
jq '.metadata' work/api/phase1/graph.json # what was actually scanned
cat work/api/phase1/scan-coverage.json # what could NOT be scanned, and whySe for reproduzível, os artefatos acima são exatamente o que um relatório de bug precisa.