abhigyanpatwari/GitNexus · error
Cannot safely encode CSV string-list item: ${JSON.stringify(
Error message
Cannot safely encode CSV string-list item: ${JSON.stringify(unsafe)} What it means
formatCSVStringArray() in gitnexus/src/core/lbug/csv-generator.ts renders a string list as a bracketed, comma-joined cell ([a,b,c]) for LadybugDB's CSV bulk load. The cell format has no quoting/escaping mechanism, so any item containing a comma, bracket, single or double quote, CR, or LF (regex /[,\[\]'"\n\r]/) cannot be encoded unambiguously and the generator throws rather than emit a row that would silently corrupt the loaded graph.
Source
Thrown at gitnexus/src/core/lbug/csv-generator.ts:142
/**
* A numeric column that may legitimately have NO value.
*
* `escapeCSVNumber` substitutes a sentinel (-1) for absence, which is right
* where every row has a span and wrong where absence is the fact being
* recorded. An empty field is loaded as NULL by COPY, so the column can say
* "there is no line here" instead of pointing at line -1.
*/
export const escapeCSVNullableNumber = (value: unknown): string =>
typeof value === 'number' && Number.isFinite(value) ? String(value) : '';
const formatCSVStringArray = (value: unknown): string => {
const items = Array.isArray(value)
? value.filter((item): item is string => typeof item === 'string')
: [];
const unsafe = items.find((item) => /[,\[\]'"\n\r]/.test(item));
if (unsafe !== undefined) {
throw new Error(`Cannot safely encode CSV string-list item: ${JSON.stringify(unsafe)}`);
}
return `[${items.join(',')}]`;
};
// ============================================================================
// CONTENT EXTRACTION (lazy — reads from disk on demand)
// ============================================================================
const BINARY_SAMPLE_CHARS = 1000;
const UNICODE_REPLACEMENT_CHAR = 0xfffd;
/**
* Did this text come from a binary payload? Density of non-printables over the
* first {@link BINARY_SAMPLE_CHARS} characters, above 10%.
*
* U+FFFD counts, and it is the character that matters most here (#2889). Every
* source file enters the pipeline through a `utf-8` decode — the content cache
* below reads with `fs.readFile(path, 'utf-8')`, and the parse worker decodesView on GitHub (pinned to 0d1aed942f)
Solutions
- Read the offending item from the message (it is JSON.stringify'd) and locate which file/symbol produced it, usually via the item's text in a grep of the repo
- If the file is generated or irrelevant, exclude it with .gitnexusignore and re-run analyze
- If a legitimate identifier must be indexed, report it upstream — the parser should sanitize/normalize such strings before they reach the CSV layer rather than users losing the file
Example fix
// before: parser emits raw annotation text props.decorators = ['@Foo(x="a,b")']; // after: strip unsafe punctuation before emit props.decorators = props.decorators.map((d) => d.replace(/[,\[\]'"\n\r]/g, ''));
Defensive patterns
Strategy: validation
Validate before calling
const CSV_UNSAFE = /[,\[\]'"\n\r]/;
function sanitizeStringList(items: string[]): string[] {
return items.map((item) => CSV_UNSAFE.test(item) ? item.replace(CSV_UNSAFE, ' ') : item);
} Type guard
function isCsvSafeStringArray(value: unknown): value is string[] {
return (
Array.isArray(value) &&
value.every((item) => typeof item === 'string' && !/[,\[\]'"\n\r]/.test(item))
);
} Try / catch
try {
await emitGraph(graph);
} catch (err) {
if (err instanceof Error && err.message.startsWith('Cannot safely encode CSV string-list item')) {
// The JSON.stringify'd item is in the message — locate its source file, exclude or report upstream;
// retrying unchanged reproduces the same row.
}
throw err;
} Prevention
- When writing parsers/plugins, normalize punctuation out of array-valued identifiers before attaching them as graph properties
- Prefer structured properties (numbers, ids) over raw source substrings for anything list-shaped
- When the error fires, use the printed item text to grep the repo and identify the offending file quickly
When it happens
Trigger: A graph property emitted as a string array where some item contains a comma or quote — e.g. symbol/decorator names carried from source (annotations like @Foo(x="a,b"), COBOL copybook names, import lists), file paths containing quotes, or generated code whose string literals become identifiers.
Common situations: Indexing languages whose decorator/annotation text is captured verbatim into array properties; parsing generated files with punctuation-heavy identifiers; a new parser or plugin emitting raw source substrings into string arrays.
Related errors
- GraphEmitSink: ${errors.length} streamed CSV writer(s) hit a
- [lbug-load] node COPY also failed while relationship emit wa
- LadybugDB not initialized for repo "${repoId}". Call initLbu
- withRetry: maxAttempts must be >= 1, got ${opts.maxAttempts}
- [understand-quickly] expected id of the form "owner/repo", g
AI-assisted analysis of abhigyanpatwari/GitNexus@0d1aed942f (2026-08-20).
Data as JSON: /api/errors/05be1b4e0db2cd29.
Report an issue: GitHub.