Skip to content
This repository was archived by the owner on May 29, 2026. It is now read-only.

Commit 04aece1

Browse files
sugyanclaude
andauthored
Fix Claude CLI validation to use fallback instead of exit on detection failure (#270)
* Fix Claude CLI validation to use fallback instead of exit on detection failure - Change validateClaudeCli to show warnings instead of exiting when detectClaudeCliPath fails - Use original claudePath as fallback when script path detection fails - Update warning message to indicate potential issues but continue execution - Addresses issue #225 and anthropics/claude-code #5823 for native installations 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com> * Replace console.* with logger and unify validation logging to cli category - Replace all console.warn/console.error calls with logger.cli.* in validation.ts - Unify logger.validation.debug calls to logger.cli.debug for consistency - Remove unused logger.validation category from logger.ts - All CLI startup and validation logging now uses single logger.cli category 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com> * Update CLAUDE.md to include explicit label usage in PR creation process - Add example gh pr create command with --label flags - Clarify how to specify appropriate labels when creating PRs - Improve developer workflow documentation consistency 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com> * Update README to reflect native binary installation support - Remove "not supported" limitation for native binary installation - Clarify that script path detection may show warnings but application works correctly - More accurate description of the current behavior with native installations 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent 6cb8071 commit 04aece1

4 files changed

Lines changed: 37 additions & 47 deletions

File tree

CLAUDE.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,10 @@ cd backend && deno task build # Local building
254254

255255
1. Create feature branch: `git checkout -b feature/name`
256256
2. Commit changes (Lefthook runs `make check`)
257-
3. Push and create PR with appropriate labels
257+
3. Push and create PR with appropriate labels:
258+
```bash
259+
gh pr create --title "..." --body "..." --label "bug" --label "backend"
260+
```
258261
4. Include Type of Change checkboxes and description
259262
5. Request review and merge after approval
260263

README.md

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -211,11 +211,7 @@ claude-code-webui --claude-path "$(asdf which claude)"
211211
```
212212

213213
**Native Binary Installation:**
214-
Currently **not supported** due to TypeScript SDK limitations. Please use npm/yarn installation:
215-
216-
```bash
217-
npm install -g @anthropic-ai/claude-code
218-
```
214+
Supported. The application will automatically detect and fall back to using the native binary if script path detection fails.
219215

220216
**Debug Mode:**
221217
Use `--debug` flag for detailed error information:

backend/cli/validation.ts

Lines changed: 32 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ const DOUBLE_BACKSLASH_REGEX = /\\\\/g;
2828
*/
2929
async function parseCmdScript(cmdPath: string): Promise<string | null> {
3030
try {
31-
logger.validation.debug(`Parsing Windows .cmd script: ${cmdPath}`);
31+
logger.cli.debug(`Parsing Windows .cmd script: ${cmdPath}`);
3232
const cmdContent = await readTextFile(cmdPath);
3333

3434
// Extract directory of the .cmd file for resolving relative paths
@@ -45,32 +45,26 @@ async function parseCmdScript(cmdPath: string): Promise<string | null> {
4545
const relativePath = pathMatch[1];
4646
const absolutePath = join(cmdDir, relativePath);
4747

48-
logger.validation.debug(`Found CLI script reference: ${relativePath}`);
49-
logger.validation.debug(`Resolved absolute path: ${absolutePath}`);
48+
logger.cli.debug(`Found CLI script reference: ${relativePath}`);
49+
logger.cli.debug(`Resolved absolute path: ${absolutePath}`);
5050

5151
// Verify the resolved path exists
5252
if (await exists(absolutePath)) {
53-
logger.validation.debug(`.cmd parsing successful: ${absolutePath}`);
53+
logger.cli.debug(`.cmd parsing successful: ${absolutePath}`);
5454
return absolutePath;
5555
} else {
56-
logger.validation.debug(
57-
`Resolved path does not exist: ${absolutePath}`,
58-
);
56+
logger.cli.debug(`Resolved path does not exist: ${absolutePath}`);
5957
}
6058
} else {
61-
logger.validation.debug(
62-
`Could not extract relative path from: ${fullPath}`,
63-
);
59+
logger.cli.debug(`Could not extract relative path from: ${fullPath}`);
6460
}
6561
} else {
66-
logger.validation.debug(
67-
`No CLI script execution pattern found in .cmd content`,
68-
);
62+
logger.cli.debug(`No CLI script execution pattern found in .cmd content`);
6963
}
7064

7165
return null;
7266
} catch (error) {
73-
logger.validation.debug(
67+
logger.cli.debug(
7468
`Failed to parse .cmd script: ${error instanceof Error ? error.message : String(error)}`,
7569
);
7670
return null;
@@ -202,7 +196,7 @@ export async function detectClaudeCliPath(
202196
});
203197
} catch (error) {
204198
// Log error for debugging but don't crash the application
205-
logger.validation.debug(
199+
logger.cli.debug(
206200
`PATH wrapping detection failed: ${error instanceof Error ? error.message : String(error)}`,
207201
);
208202
pathWrappingResult = null;
@@ -215,7 +209,7 @@ export async function detectClaudeCliPath(
215209

216210
// Try Windows .cmd parsing fallback if PATH wrapping didn't work
217211
if (isWindows && claudePath.endsWith(".cmd")) {
218-
logger.validation.debug(
212+
logger.cli.debug(
219213
"PATH wrapping method failed, trying .cmd parsing fallback...",
220214
);
221215
try {
@@ -238,7 +232,7 @@ export async function detectClaudeCliPath(
238232
return { scriptPath: cmdParsedPath, versionOutput };
239233
}
240234
} catch (fallbackError) {
241-
logger.validation.debug(
235+
logger.cli.debug(
242236
`.cmd parsing fallback failed: ${fallbackError instanceof Error ? fallbackError.message : String(fallbackError)}`,
243237
);
244238
}
@@ -280,9 +274,9 @@ export async function validateClaudeCli(
280274
const candidates = await runtime.findExecutable("claude");
281275

282276
if (candidates.length === 0) {
283-
console.error("❌ Claude CLI not found in PATH");
284-
console.error(" Please install claude-code globally:");
285-
console.error(
277+
logger.cli.error("❌ Claude CLI not found in PATH");
278+
logger.cli.error(" Please install claude-code globally:");
279+
logger.cli.error(
286280
" Visit: https://claude.ai/code for installation instructions",
287281
);
288282
exit(1);
@@ -292,27 +286,27 @@ export async function validateClaudeCli(
292286
if (isWindows && candidates.length > 1) {
293287
const cmdCandidate = candidates.find((path) => path.endsWith(".cmd"));
294288
claudePath = cmdCandidate || candidates[0];
295-
logger.validation.debug(
289+
logger.cli.debug(
296290
`Found Claude CLI candidates: ${candidates.join(", ")}`,
297291
);
298-
logger.validation.debug(
292+
logger.cli.debug(
299293
`Using Claude CLI path: ${claudePath} (Windows .cmd preferred)`,
300294
);
301295
} else {
302296
// Use the first candidate (most likely to be the correct one)
303297
claudePath = candidates[0];
304-
logger.validation.debug(
298+
logger.cli.debug(
305299
`Found Claude CLI candidates: ${candidates.join(", ")}`,
306300
);
307-
logger.validation.debug(`Using Claude CLI path: ${claudePath}`);
301+
logger.cli.debug(`Using Claude CLI path: ${claudePath}`);
308302
}
309303
}
310304

311305
// Check if this is a Windows .cmd file for enhanced debugging
312306
const isCmdFile = claudePath.endsWith(".cmd");
313307

314308
if (isWindows && isCmdFile) {
315-
logger.validation.debug(
309+
logger.cli.debug(
316310
"Detected Windows .cmd file - fallback parsing available if needed",
317311
);
318312
}
@@ -328,22 +322,22 @@ export async function validateClaudeCli(
328322
}
329323
return detection.scriptPath;
330324
} else {
331-
// Exit with clear error when detection fails
332-
console.error("❌ Claude CLI script path detection failed");
333-
console.error(
334-
" This can happen when the Claude CLI installation is incompatible with this application.",
335-
);
336-
console.error("");
337-
console.error(
338-
" Try specifying a custom `claude` command path using: --claude-path /path/to/claude",
325+
// Show warning but continue with fallback when detection fails
326+
logger.cli.warn("⚠️ Claude CLI script path detection failed");
327+
logger.cli.warn(
328+
" Falling back to using the claude executable directly.",
339329
);
340-
console.error("");
341-
console.error(` Attempted to detect script path from: ${claudePath}`);
342-
exit(1);
330+
logger.cli.warn(" This may not work properly, but continuing anyway.");
331+
logger.cli.warn("");
332+
logger.cli.warn(` Using fallback path: ${claudePath}`);
333+
if (detection.versionOutput) {
334+
logger.cli.info(`✅ Claude CLI found: ${detection.versionOutput}`);
335+
}
336+
return claudePath;
343337
}
344338
} catch (error) {
345-
console.error("❌ Failed to validate Claude CLI");
346-
console.error(
339+
logger.cli.error("❌ Failed to validate Claude CLI");
340+
logger.cli.error(
347341
` Error: ${error instanceof Error ? error.message : String(error)}`,
348342
);
349343
exit(1);

backend/utils/logger.ts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,6 @@ export const logger = {
6565
// CLI and startup logging
6666
cli: getLogger(["cli"]),
6767

68-
// Claude CLI validation and detection
69-
validation: getLogger(["validation"]),
70-
7168
// Chat handling and streaming
7269
chat: getLogger(["chat"]),
7370

0 commit comments

Comments
 (0)