{"record":{"id":"8f058b5f0b315e3d","repo":"can1357/oh-my-pi","slug":"sqlite-query-parameter-q-cannot-be-empty","errorCode":null,"errorMessage":"SQLite query parameter 'q' cannot be empty","messagePattern":"SQLite query parameter 'q' cannot be empty","errorType":"validation","errorClass":"ToolError","httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/tools/sqlite-reader.ts","lineNumber":572,"sourceCode":"\ttry {\n\t\treturn looksLikeSqlite(await Bun.file(absolutePath).slice(0, SQLITE_MAGIC.byteLength).bytes());\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nexport 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","sourceCodeStart":554,"sourceCodeEnd":590,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/tools/sqlite-reader.ts#L554-L590","documentation":"Thrown when the 'q' parameter is present but empty or whitespace-only. An empty raw query has no meaning, so the parser rejects it explicitly instead of issuing a useless query to SQLite.","triggerScenarios":"URLs like 'db.sqlite?q=' or 'db.sqlite?q=%20%20'; an upstream variable holding the SQL being empty; template interpolation producing a blank q value.","commonSituations":"Optional SQL variable that came through as empty string; form/UI field left blank; trimmed-out query after sanitization upstream.","solutions":["Provide a non-empty SQL statement in q","Omit the q param entirely if you meant to use the table/list API","Check upstream code for empty-string defaults overwriting the query"],"exampleFix":"// before\nconst url = `db.sqlite?q=${sql.trim()}` // sql was empty\n// after\nif (!sql.trim()) throw new Error('sql required');\nconst url = `db.sqlite?q=${encodeURIComponent(sql)}`","handlingStrategy":"validation","validationCode":"if (q != null && !q.trim()) {\n  throw new Error('q param present but empty; provide SQL or omit q');\n}","typeGuard":null,"tryCatchPattern":"try {\n  await reader.read(`db.sqlite?q=${encodeURIComponent(q)}`);\n} catch (err) {\n  if (err instanceof ToolError && err.message.includes(\"'q' cannot be empty\")) {\n    // skip the call or surface a 'no query provided' state\n  } else throw err;\n}","preventionTips":["Check sql.trim().length > 0 before interpolating into the URL","Omit the q param entirely when there is no query","Guard upstream defaults that produce empty strings"],"tags":["sqlite","validation","empty-value","query-parameters"],"backgroundTag":"missing-or-empty-parameter","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}