can1357/oh-my-pi · error
Symbol "${symbol}" not found on line ${lineNumber}
Error message
Symbol "${symbol}" not found on line ${lineNumber} What it means
resolveSymbolColumn reads the target line from the file and locates the symbol text to compute the character column, first with exact matching, then with a looser fallback. If the symbol appears nowhere on that line, it throws this error so callers get a precise message instead of a column-0 guess.
Source
Thrown at packages/coding-agent/src/lsp/utils.ts:709
const occurrence = Math.max(1, Number.parseInt(match[2], 10));
return { symbol: match[1], occurrence };
}
export async function resolveSymbolColumn(filePath: string, line: number, symbolSpec?: string): Promise<number> {
const lineNumber = Math.max(1, line);
try {
const fileText = await Bun.file(filePath).text();
const lines = fileText.split("\n");
const targetLine = lines[lineNumber - 1] ?? "";
if (!symbolSpec) {
return firstNonWhitespaceColumn(targetLine);
}
const { symbol, occurrence } = parseSymbolSpec(symbolSpec);
const exactIndexes = findSymbolMatchIndexes(targetLine, symbol);
const fallbackIndexes = exactIndexes.length > 0 ? exactIndexes : findSymbolMatchIndexes(targetLine, symbol, true);
if (fallbackIndexes.length === 0) {
throw new Error(`Symbol "${symbol}" not found on line ${lineNumber}`);
}
if (occurrence > fallbackIndexes.length) {
throw new Error(
`Symbol "${symbol}" occurrence ${occurrence} is out of bounds on line ${lineNumber} (found ${fallbackIndexes.length})`,
);
}
return fallbackIndexes[occurrence - 1];
} catch (error) {
if (isEnoent(error)) {
throw new Error(`File not found: ${filePath}`);
}
throw error;
}
}
export async function readLocationContext(filePath: string, line: number, contextLines = 1): Promise<string[]> {
const targetLine = Math.max(1, line);
const surrounding = Math.max(0, contextLines);View on GitHub (pinned to 9690622007)
Solutions
- Re-read the file and supply the current line number where the symbol appears.
- Verify spelling and casing of the symbol text matches the source line exactly (or as a substring the fallback matcher accepts).
- Use `symbol#N` only after confirming the symbol occurs on that line.
- Drop the `symbol` param if you can supply an exact character position instead (non-project-aware path).
Example fix
// before
await lspTool.execute({ action: "definition", file: "a.ts", line: 42, symbol: "myFunc" }); // line 42 no longer has myFunc
// after
const lines = (await Bun.file("a.ts").text()).split("\n");
const line = lines.findIndex(l => l.includes("myFunc")) + 1;
await lspTool.execute({ action: "definition", file: "a.ts", line, symbol: "myFunc" }); Defensive patterns
Strategy: validation
Validate before calling
import * as fs from "node:fs/promises";
async function lineContainsSymbol(file: string, line: number, symbol: string) {
const text = (await fs.readFile(file, "utf8")).split("\n")[line - 1] ?? "";
return text.includes(symbol);
}
// call only if await lineContainsSymbol(file, line, symbol) Try / catch
try {
return await lspTool.execute({ action: "definition", file, line, symbol });
} catch (err) {
if (err instanceof Error && err.message.includes("not found on line")) {
const line2 = await findLineContaining(file, symbol);
return lspTool.execute({ action: "definition", file, line: line2, symbol });
} throw err;
} Prevention
- Re-read the file immediately before issuing position+symbol calls to avoid stale line numbers.
- Use bare identifiers as they literally appear on the line (strip qualification).
- Compute line numbers programmatically from current file content rather than cached positions.
When it happens
Trigger: Calling execute() with a `symbol` param whose text does not appear (even with fallback matching) on the given `line` of `file` — e.g. stale line numbers after the file changed, or a typo in the symbol name.
Common situations: Line numbers taken from an older read of the file that has since been edited; copying a qualified name (`Foo.bar`) that appears on the line only as `bar`; case/whitespace mismatch.
Related errors
- symbol is required for project-aware ${action}; pass symbol=
- Symbol "${symbol}" occurrence ${occurrence} is out of bounds
- File not found: ${filePath}
- Unsupported language '{value}'. Supported: {}
- Unable to infer language from file extension: {}. Specify `l
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/08b69564b5679abf.
Report an issue: GitHub.