Skip to content
Canopy is in pre-release. These docs describe the product at its public launch — commands, tool names, and integration examples reflect what you'll see once binaries ship. Join the waitlist →

Debug Symbol Resolution Issues

Symbol resolution issues show up as a locate question returning no match, a dependents answer that looks incomplete, or an imports answer missing entries you know exist. This guide walks the diagnosis from question phrasing down to a full index rebuild.

Phrasing picks the recipe. Name the entity type and put paths and symbols in backticks so the classifier locks on — vague phrasing falls back to a weaker semantic search:

Terminal window
# Strong: entity type named, symbol backticked
canopy answer "where is the function `createPayment` defined?"
# Weak: no type, no backticks — falls back to semantic search
canopy answer "createPayment location"

If the strong form finds the symbol, the index is fine and the original question was under-specified.

Ask for the file’s surface and the directory’s symbols:

Terminal window
canopy answer "public surface of `src/lib/payments.ts`"
canopy answer "list functions defined in `src/lib/`"

If the symbol you expect is absent from both answers, Canopy never extracted it. The usual causes: the file is excluded by an ignore layer, the index is stale, or the file failed to parse.

Terminal window
canopy index --list-ignored

This prints what would be indexed vs skipped, grouped by top-level directory, without indexing. If your file is in the skip list, one of the ignore layers caught it: the bundled defaults (build artifacts, vendored dependencies), .gitignore, .canopyignore, or an --ignore-pattern glob. Re-run with --no-default-ignore, --no-gitignore, or --no-canopyignore to attribute the skip to a specific layer, then adjust that layer.

For an import you expect but don’t see:

Terminal window
canopy answer "what does `src/api/orders.ts` import?"

For reachability — whether anything actually connects to the module:

Terminal window
canopy answer "is `src/lib/payments.ts` reachable?"
canopy answer "what depends on `src/lib/payments.ts`?"

An unreachable module isn’t necessarily broken: it may be invoked at runtime through a dynamic path, be a new module not yet wired in, or be an intentionally standalone script. Use context to decide whether “dead code” is a real finding.

Terminal window
canopy doctor

The report covers install info, index status, and the active backend. If the index is missing or points at a different repo root than you expect, this is where it shows.

Terminal window
canopy index . # incremental — picks up changed files
canopy index . --full # wipe and re-index from scratch

Use --full when incremental state is suspect — after large-scale moves, renames across directories, or an interrupted index run. During development, canopy serve --watch re-indexes changed files automatically so the MCP answers stay current.

  • Dynamic imports with computed paths can’t be resolved at index time. A module loaded via a string built at runtime won’t appear as a static edge.
  • String-path references (a path mentioned in a config file rather than imported) don’t count as dependents. The dependents answer covers static imports.

These are properties of static analysis, not index defects. When a dependents answer looks short, check whether the missing consumers reference the module dynamically.