{"record":{"id":"36ef94c7365b2eb2","repo":"can1357/oh-my-pi","slug":"sqlite-query-parameters-require-a-table-selector-o","errorCode":null,"errorMessage":"SQLite query parameters require a table selector or q=SELECT...","messagePattern":"SQLite query parameters require a table selector or q=SELECT\\.\\.\\.","errorType":"validation","errorClass":"ToolError","httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/tools/sqlite-reader.ts","lineNumber":579,"sourceCode":"export function parseSqliteSelector(subPath: string, queryString: string): SqliteSelector {\n\tconst normalizedSubPath = subPath.replace(/^:+/, \"\").trim();\n\tconst params = new URLSearchParams(queryString);\n\tconst rawQuery = params.get(\"q\");\n\n\tif (rawQuery !== null) {\n\t\tconst otherKeys = [...params.keys()].filter(key => key !== \"q\");\n\t\tif (normalizedSubPath || otherKeys.length > 0) {\n\t\t\tthrow new ToolError(\"SQLite raw queries cannot be combined with table selectors or pagination\");\n\t\t}\n\t\tif (!rawQuery.trim()) {\n\t\t\tthrow new ToolError(\"SQLite query parameter 'q' cannot be empty\");\n\t\t}\n\t\treturn { kind: \"raw\", sql: rawQuery };\n\t}\n\n\tif (!normalizedSubPath) {\n\t\tif (params.size > 0) {\n\t\t\tthrow new ToolError(\"SQLite query parameters require a table selector or q=SELECT...\");\n\t\t}\n\t\treturn { kind: \"list\" };\n\t}\n\n\tconst separatorIndex = normalizedSubPath.indexOf(\":\");\n\tconst table = separatorIndex === -1 ? normalizedSubPath : normalizedSubPath.slice(0, separatorIndex);\n\tconst key = separatorIndex === -1 ? undefined : normalizedSubPath.slice(separatorIndex + 1);\n\tif (!table) {\n\t\tthrow new ToolError(\"SQLite selectors must include a table name\");\n\t}\n\n\tif (key !== undefined && key.length > 0) {\n\t\tif (params.size > 0) {\n\t\t\tthrow new ToolError(\"SQLite row lookups cannot be combined with query parameters\");\n\t\t}\n\t\treturn { kind: \"row\", table, key };\n\t}\n","sourceCodeStart":561,"sourceCodeEnd":597,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/tools/sqlite-reader.ts#L561-L597","documentation":"Thrown when query parameters are supplied but there is neither a table sub-path nor a q= raw query. Parameters like limit/where/order only make sense in table-select mode, so a bare path with params is ambiguous and rejected.","triggerScenarios":"'db.sqlite?limit=5' with no table; a URL where the table segment was dropped but params kept; sub-path consisting only of ':' leaving an empty table.","commonSituations":"Constructing URLs from parts where the table variable is empty; renaming endpoints and forgetting the table segment; copy-paste that lost the '/table' portion.","solutions":["Add the table name: 'db.sqlite/users?limit=5'","Add a raw query: 'db.sqlite?q=SELECT ...'","Remove the stray params if you intended a plain database listing"],"exampleFix":"// before\ndb.sqlite?limit=5\n// after\ndb.sqlite/users?limit=5","handlingStrategy":"validation","validationCode":"if (!table && !rawSql && Object.keys(params).length > 0) {\n  throw new Error('query params require a table path or q=...');\n}","typeGuard":null,"tryCatchPattern":"try {\n  await reader.read(url);\n} catch (err) {\n  if (err instanceof ToolError && err.message.includes('require a table selector')) {\n    // fix URL construction: ensure the table segment is present\n  } else throw err;\n}","preventionTips":["Assert the table variable is non-empty before building the URL","Pair params with a table path in a single builder function","Drop params when the path has no table selector"],"tags":["sqlite","validation","api-misuse","query-parameters"],"backgroundTag":"missing-required-parameter","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}