windmill-labs/windmill · warning

Could not open in Claude Desktop: ${errorMessage}

Error message

Could not open in Claude Desktop: ${errorMessage}

What it means

Warning from `wmill app new`'s outer catch around the whole 'Open in Claude Desktop' block. It fires when any awaited step before the deep-link exec fails: writing/seeding .claude/launch.json (mkdir/stat/writeFile errors), or spawning `claude --session-id <uuid> -p ...` to create the session (exec rejection). The CLI prints the error message and tells the user to manually run `cd <folder> && claude`.

Source

Thrown at cli/src/commands/app/new.ts:876

        // the deep link doesn't pass through a shell — `sessionId` is a UUID
        // and absAppDir is URI-encoded inside the URL today, but execFile
        // removes shell escaping concerns entirely.
        const deepLink = `claude://resume?session=${sessionId}&cwd=${encodeURIComponent(absAppDir)}`;
        execFile("open", [deepLink], (err) => {
          if (err) {
            log.warn(
              colors.yellow(
                `Could not open Claude Desktop deep link (${err.message}). Open it manually: ${deepLink}`
              )
            );
          } else {
            log.info(colors.bold.green("Opened in Claude Desktop!"));
          }
        });
      } catch (error: unknown) {
        const errorMessage =
          error instanceof Error ? error.message : String(error);
        log.warn(
          colors.yellow(
            `Could not open in Claude Desktop: ${errorMessage}`
          )
        );
        log.info(
          colors.gray(
            "You can manually run: cd " + folderName + " && claude"
          )
        );
      }
    }
  }
}

const command = new Command()
  .description("create a new raw app from a template")
  .option(
    "--summary <summary:string>",

View on GitHub (pinned to e474e8803c)

Solutions

  1. Check that the `claude` CLI is installed and works: run `claude --version` and `claude -p 'hi'` in the app folder; install/update Claude Code if missing.
  2. Run the manual fallback the CLI prints: `cd <appFolder> && claude`, then start the preview with `wmill app dev`.
  3. Check filesystem permissions on the new app directory; ensure .claude/launch.json can be created (or create it manually).
  4. If the error came from the claude command itself, read its message (auth/login errors) and run `claude /login` or fix the API key, then retry `wmill app new`.
  5. Use --open-in-desktop=false (or answer No at the prompt) to skip this optional step entirely; app scaffolding is unaffected.

Example fix

// before: failing inside the block
await writeFile(launchPath, launchJson, "utf-8");
// after: caller-side guard before running app new
const claudeBin = which.sync("claude", { nothrow: true });
if (!claudeBin) {
  console.log('claude CLI not found; skipping desktop open (run `cd dir && claude` later).');
}
Defensive patterns

Strategy: try-catch

Validate before calling

import { which } from "@cliffy/command"; // or check PATH manually
const claudeOnPath = !!await new Promise<boolean>((res) =>
  execFile("claude", ["--version"], (err) => res(!err)));
if (!claudeOnPath) console.warn('claude CLI missing; desktop-open step will fail.');

Type guard

function isNodeSystemError(e: unknown): e is NodeJS.ErrnoException {
  return e instanceof Error && typeof (e as NodeJS.ErrnoException).code === "string";
}

Try / catch

try {
  await seedLaunchJson(absAppDir);
  await createClaudeSession(absAppDir);
  openDeepLink(sessionId, absAppDir);
} catch (error) {
  const msg = error instanceof Error ? error.message : String(error);
  log.warn(`Could not open in Claude Desktop: ${msg}`);
  log.info(`Fallback: cd ${folderName} && claude`);
}

Prevention

When it happens

Trigger: `wmill app new` reached the desktop-open step and either (a) the filesystem rejects the launch.json seeding (read-only dir, permission denied on mkdir/writeFile), or (b) the spawned `claude` CLI binary exits non-zero or cannot be spawned (claude not on PATH, command failed), rejecting the wrapped exec promise.

Common situations: Claude Code CLI (`claude`) not installed or not on PATH while Claude Desktop is; corrupted npm/bun global install of claude-code; app directory created on a read-only mount; .claude/launch.json exists with restrictive permissions; claude CLI failing auth on first run.

Related errors


AI-assisted analysis of windmill-labs/windmill@e474e8803c (2026-09-03). Data as JSON: /api/errors/58dcf1d99795dd34. Report an issue: GitHub.