{"record":{"id":"a376ec2116e3451c","repo":"can1357/oh-my-pi","slug":"cannot-search-archive-member-s-archiveunreadab","errorCode":null,"errorMessage":"Cannot search archive member(s): ${archiveUnreadable.join(\", \")}. Read the member with `read <archive>:<member>` and inspect the returned text, or pass a UTF-8 text member.","messagePattern":"Cannot search archive member\\(s\\): (.+?)\\. Read the member with `read <archive>:<member>` and inspect the returned text, or pass a UTF-8 text member\\.","errorType":"validation","errorClass":"ToolError","httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/tools/grep.ts","lineNumber":1014,"sourceCode":"\t\t\t\t\tcwd: this.session.cwd,\n\t\t\t\t\tsettings: this.session.settings,\n\t\t\t\t\tsignal,\n\t\t\t\t\tarchiveDisplayMap,\n\t\t\t\t\tlocalProtocolOptions: this.session.localProtocolOptions,\n\t\t\t\t\tskills: this.session.skills,\n\t\t\t\t\tsessionFile: this.session.getSessionFile() ?? undefined,\n\t\t\t\t});\n\t\t\t\tconst searchablePaths = internalResolution.paths;\n\t\t\t\tconst { virtualResources, virtualPathSet, virtualInputIndexes } = internalResolution;\n\t\t\t\tconst rangesByAbsPath = new Map<string, LineRange[]>();\n\n\t\t\t\tif (\n\t\t\t\t\tarchiveUnreadable.length > 0 &&\n\t\t\t\t\tsearchablePaths.length === archiveUnreadable.length &&\n\t\t\t\t\tvirtualResources.length === 0\n\t\t\t\t) {\n\t\t\t\t\t// All inputs were archive selectors we couldn't materialize; surface the\n\t\t\t\t\t// reason instead of a downstream \"path not found\" from the scope resolver.\n\t\t\t\t\tthrow new ToolError(\n\t\t\t\t\t\t`Cannot search archive member(s): ${archiveUnreadable.join(\", \")}. ` +\n\t\t\t\t\t\t\t`Read the member with \\`read <archive>:<member>\\` and inspect the returned text, ` +\n\t\t\t\t\t\t\t`or pass a UTF-8 text member.`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tconst normalizedContextBefore = this.#contextOverride ?? this.session.settings.get(\"grep.contextBefore\");\n\t\t\t\tconst normalizedContextAfter = this.#contextOverride ?? this.session.settings.get(\"grep.contextAfter\");\n\t\t\t\tconst ignoreCase = !(caseSensitive ?? true);\n\t\t\t\tconst useGitignore = gitignore ?? true;\n\t\t\t\tconst patternHasNewline = normalizedPattern.includes(\"\\n\") || normalizedPattern.includes(\"\\\\n\");\n\t\t\t\tconst effectiveMultiline = patternHasNewline;\n\n\t\t\t\tlet searchPath: string;\n\t\t\t\tlet scopePath: string;\n\t\t\t\tlet globFilter: string | undefined;\n\t\t\t\tlet isDirectory: boolean;\n\t\t\t\tlet multiTargets: ResolvedSearchTarget[] | undefined;","sourceCodeStart":996,"sourceCodeEnd":1032,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/tools/grep.ts#L996-L1032","documentation":"Every path passed to grep was an archive member selector (e.g. archive.tar.gz:inner.txt) that could not be materialized as searchable text — typically because the member is binary or not decodable as UTF-8 — and there were no other searchable or virtual paths to fall back on. The tool surfaces this reason instead of letting the scope resolver emit a confusing \"path not found\".","triggerScenarios":"grep with path set exclusively to archive member selectors whose contents cannot be extracted as UTF-8 text, e.g. `grep tgz:data.tar.gz:bin/image.png` or a compressed binary member.","commonSituations":"Grepping inside a tar/zip for a binary asset by mistake; typos in the member name selecting a binary file; expecting the tool to search binary contents.","solutions":["Extract the member's text via `read <archive>:<member>` and inspect the returned text","Pass a UTF-8 text member of the archive instead of the binary one","Include at least one normal (non-archive) path in the semicolon-delimited `path` list so the search can proceed on the other targets"],"exampleFix":"// before\nawait grep({ pattern: \"version\", path: \"app.tar.gz:assets/logo.png\" });\n// after\nconst pkg = await read(\"app.tar.gz:package.json\");\nawait grep({ pattern: \"version\", path: \"app.tar.gz:package.json\" });","handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  await grep({ pattern, path: \"data.tar.gz:blob.bin\" });\n} catch (err) {\n  if (err instanceof ToolError && err.message.startsWith(\"Cannot search archive member\")) {\n    const text = await read(\"data.tar.gz:README.md\"); // fall back to a text member\n  } else throw err;\n}","preventionTips":["Only select UTF-8 text members for grep; read binary members instead","Verify member names/types by reading the archive listing first"],"tags":["grep","archive","binary-content"],"backgroundTag":"archive-member-not-searchable","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}