{"record":{"id":"c9ce46cb4a3d55cd","repo":"windmill-labs/windmill","slug":"could-not-generate-tsconfig-error-instanceof-er","errorCode":null,"errorMessage":"Could not generate tsconfig: ${error instanceof Error ? error.message : error}","messagePattern":"Could not generate tsconfig: (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"cli/src/commands/init/init.ts","lineNumber":247,"sourceCode":"          }\n        }\n      } catch (error) {\n        log.warn(\n          `Could not check backend for git-sync settings: ${(error as Error).message}`\n        );\n        log.info(\"Continuing with default settings\");\n      }\n    }\n  }\n\n  await refreshPrompts({ yes: opts.useDefault === true });\n\n  // Generate the IDE tsconfig (managed tsconfig.wmill.json + user tsconfig.json\n  // that extends it). Independent of any workspace binding — it's purely local.\n  try {\n    await refreshTsconfig({ yes: opts.useDefault === true });\n  } catch (error) {\n    log.warn(\n      `Could not generate tsconfig: ${\n        error instanceof Error ? error.message : error\n      }`\n    );\n  }\n\n  // Generate resource type namespace (needs a bound workspace)\n  if (didBindWorkspace && boundProfile) {\n    try {\n      // Cache the bound profile so resolveWorkspace doesn't re-resolve and prompt again\n      const rtOpts = { ...opts } as GlobalOptions;\n      (rtOpts as any).__secret_workspace = boundProfile;\n      await generateRTNamespace(rtOpts);\n    } catch (error) {\n      log.warn(\n        `Could not pull resource types and generate TypeScript namespace: ${\n          error instanceof Error ? error.message : error\n        }`","sourceCodeStart":229,"sourceCodeEnd":265,"githubUrl":"https://github.com/windmill-labs/windmill/blob/e474e8803ce2ff5c2df09a58dab51d45f5c922ca/cli/src/commands/init/init.ts#L229-L265","documentation":"After `wmill init` writes wmill.yaml, it generates a managed TypeScript tsconfig (tsconfig.wmill.json plus a user tsconfig.json extending it) via refreshTsconfig. Any error thrown by that purely local generation step is caught and logged as this warning; init continues without the IDE tsconfig.","triggerScenarios":"Calling `wmill init` when refreshTsconfig fails — typically a filesystem error writing tsconfig.wmill.json/tsconfig.json (read-only directory, permission denied, existing tsconfig.json that cannot be updated without confirmation) or an error composing the config from the current directory state.","commonSituations":"Running init in a read-only mount or directory owned by another user; existing tsconfig.json with restrictive permissions; running init non-interactively (CI) where refreshTsconfig would prompt for confirmation but opts.useDefault is false and no TTY is available.","solutions":["Check write permissions on the project root (where wmill.yaml was created) and re-run `wmill init`.","If a managed tsconfig already exists, delete tsconfig.wmill.json and re-run, or manually keep your tsconfig.json extending tsconfig.wmill.json.","Use `wmill init --use-default` so refreshTsconfig runs non-interactively with yes=true (avoids interactive-confirm failures in CI).","Read the warning text for the concrete cause (EACCES/EPERM => permissions; ENOTDIR => wrong working directory)."],"exampleFix":"// before\nwmill init   # in a CI job, fails to confirm tsconfig overwrite\n// after\nwmill init --use-default","handlingStrategy":"try-catch","validationCode":"import { stat } from \"node:fs/promises\";\n// confirm the project root is writable before running init\ntry {\n  await stat(\".\");\n  await writeFile(\".write-test\", \"\");\n  await rm(\".write-test\");\n} catch (e) {\n  console.error(\"project directory is not writable:\", e);\n}","typeGuard":"function toErrorMessage(error: unknown): string {\n  return error instanceof Error ? error.message : String(error);\n}","tryCatchPattern":"try {\n  await refreshTsconfig({ yes: true });\n} catch (error) {\n  log.warn(`Could not generate tsconfig: ${toErrorMessage(error)}`);\n}","preventionTips":["Run `wmill init` from a writable project root, not a read-only mount.","In CI, always pass --use-default so tsconfig generation doesn't block on interactive confirmation.","If you keep a hand-written tsconfig.json, ensure it extends tsconfig.wmill.json and grant write permission when regenerating.","Check for leftover tsconfig.wmill.json with wrong ownership after switching users/containers."],"tags":["filesystem","typescript","cli","permissions"],"backgroundTag":"file-write-failed","analyzedSha":"e474e8803ce2ff5c2df09a58dab51d45f5c922ca","analyzedAt":"2026-09-03T12:38:19.024Z","contentChangedAt":"2026-09-03T12:38:19.024Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}