Skip to content

add more (sanitised) user errors to telemetry #10000

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jul 17, 2025
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions packages/wrangler/src/assets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -475,7 +475,8 @@ export function getAssetsOptions(
) {
throw new UserError(
"Cannot set run_worker_first without a Worker script.\n" +
"Please remove run_worker_first from your configuration file, or provide a Worker script in your configuration file (`main`)."
"Please remove run_worker_first from your configuration file, or provide a Worker script in your configuration file (`main`).",
{ telemetryMessage: true }
);
}

Expand Down Expand Up @@ -533,7 +534,8 @@ export function validateAssetsArgsAndConfig(
) {
throw new UserError(
"Cannot use assets and Workers Sites in the same Worker.\n" +
"Please remove either the `site` or `assets` field from your configuration file."
"Please remove either the `site` or `assets` field from your configuration file.",
{ telemetryMessage: true }
);
}

Expand Down
31 changes: 21 additions & 10 deletions packages/wrangler/src/deploy/deploy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -405,12 +405,15 @@ export default async function deploy(props: Props): Promise<{
""
).padStart(2, "0")}-${(new Date().getDate() + "").padStart(2, "0")}`;

throw new UserError(`A compatibility_date is required when publishing. Add the following to your ${configFileName(config.configPath)} file:
throw new UserError(
`A compatibility_date is required when publishing. Add the following to your ${configFileName(config.configPath)} file:
\`\`\`
${formatConfigSnippet({ compatibility_date: compatibilityDateStr }, config.configPath, false)}
\`\`\`
Or you could pass it in your terminal as \`--compatibility-date ${compatibilityDateStr}\`
See https://developers.cloudflare.com/workers/platform/compatibility-dates for more information.`);
See https://developers.cloudflare.com/workers/platform/compatibility-dates for more information.`,
{ telemetryMessage: "missing compatibiltiy date when deploying" }
);
}

const routes =
Expand Down Expand Up @@ -495,25 +498,29 @@ See https://developers.cloudflare.com/workers/platform/compatibility-dates for m
format === "service-worker"
) {
throw new UserError(
"You cannot use the service-worker format with an `assets` directory yet. For information on how to migrate to the module-worker format, see: https://developers.cloudflare.com/workers/learning/migrating-to-module-workers/"
"You cannot use the service-worker format with an `assets` directory yet. For information on how to migrate to the module-worker format, see: https://developers.cloudflare.com/workers/learning/migrating-to-module-workers/",
{ telemetryMessage: true }
);
}

if (config.wasm_modules && format === "modules") {
throw new UserError(
"You cannot configure [wasm_modules] with an ES module worker. Instead, import the .wasm module directly in your code"
"You cannot configure [wasm_modules] with an ES module worker. Instead, import the .wasm module directly in your code",
{ telemetryMessage: true }
);
}

if (config.text_blobs && format === "modules") {
throw new UserError(
`You cannot configure [text_blobs] with an ES module worker. Instead, import the file directly in your code, and optionally configure \`[rules]\` in your ${configFileName(config.configPath)} file`
`You cannot configure [text_blobs] with an ES module worker. Instead, import the file directly in your code, and optionally configure \`[rules]\` in your ${configFileName(config.configPath)} file`,
{ telemetryMessage: "[text_blobs] with an ES module worker" }
);
}

if (config.data_blobs && format === "modules") {
throw new UserError(
`You cannot configure [data_blobs] with an ES module worker. Instead, import the file directly in your code, and optionally configure \`[rules]\` in your ${configFileName(config.configPath)} file`
`You cannot configure [data_blobs] with an ES module worker. Instead, import the file directly in your code, and optionally configure \`[rules]\` in your ${configFileName(config.configPath)} file`,
{ telemetryMessage: "[text_blobs] with an ES module worker" }
);
}

Expand Down Expand Up @@ -969,7 +976,8 @@ See https://developers.cloudflare.com/workers/platform/compatibility-dates for m
"binding DB of type d1 must have a valid `id` specified [code: 10021]"
) {
throw new UserError(
"You must use a real database in the database_id configuration. You can find your databases using 'wrangler d1 list', or read how to develop locally with D1 here: https://developers.cloudflare.com/d1/configuration/local-development"
"You must use a real database in the database_id configuration. You can find your databases using 'wrangler d1 list', or read how to develop locally with D1 here: https://developers.cloudflare.com/d1/configuration/local-development",
{ telemetryMessage: "[text_blobs] with an ES module worker" }
);
}

Expand Down Expand Up @@ -1133,7 +1141,8 @@ async function publishRoutesFallback(
if (notProd) {
throw new UserError(
"Service environments combined with an API token that doesn't have 'All Zones' permissions is not supported.\n" +
"Either turn off service environments by setting `legacy_env = true`, creating an API token with 'All Zones' permissions, or logging in via OAuth"
"Either turn off service environments by setting `legacy_env = true`, creating an API token with 'All Zones' permissions, or logging in via OAuth",
{ telemetryMessage: "[text_blobs] with an ES module worker" }
);
}
logger.warn(
Expand Down Expand Up @@ -1213,7 +1222,8 @@ async function publishRoutesFallback(
continue;
} else {
throw new UserError(
`The route with pattern "${routePattern}" is already associated with another worker called "${knownScript}".`
`The route with pattern "${routePattern}" is already associated with another worker called "${knownScript}".`,
{ telemetryMessage: "route already associated with another worker" }
);
}
}
Expand Down Expand Up @@ -1318,7 +1328,8 @@ export async function updateQueueConsumers(
if (scriptName === undefined) {
// TODO: how can we reliably get the current script name?
throw new UserError(
"Script name is required to update queue consumers"
"Script name is required to update queue consumers",
{ telemetryMessage: true }
);
}

Expand Down
3 changes: 2 additions & 1 deletion packages/wrangler/src/deploy/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,8 @@ export const deployCommand = createCommand({
validateArgs(args) {
if (args.nodeCompat) {
throw new UserError(
`The --node-compat flag is no longer supported as of Wrangler v4. Instead, use the \`nodejs_compat\` compatibility flag. This includes the functionality from legacy \`node_compat\` polyfills and natively implemented Node.js APIs. See https://developers.cloudflare.com/workers/runtime-apis/nodejs for more information.`
`The --node-compat flag is no longer supported as of Wrangler v4. Instead, use the \`nodejs_compat\` compatibility flag. This includes the functionality from legacy \`node_compat\` polyfills and natively implemented Node.js APIs. See https://developers.cloudflare.com/workers/runtime-apis/nodejs for more information.`,
{ telemetryMessage: true }
);
}
},
Expand Down
6 changes: 4 additions & 2 deletions packages/wrangler/src/deployment-bundle/entry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,8 @@ export async function getEntry(
if (config.pages_build_output_dir && command === "dev") {
throw new UserError(
"It looks like you've run a Workers-specific command in a Pages project.\n" +
"For Pages, please run `wrangler pages dev` instead."
"For Pages, please run `wrangler pages dev` instead.",
{ telemetryMessage: true }
);
}

Expand Down Expand Up @@ -143,7 +144,8 @@ export async function getEntry(
const migrateUrl =
"https://developers.cloudflare.com/workers/learning/migrating-to-module-workers/";
throw new UserError(
`${errorMessage}\n${addScriptName}\n${addScriptNameExamples}\n${migrateText}\n${migrateUrl}`
`${errorMessage}\n${addScriptName}\n${addScriptNameExamples}\n${migrateText}\n${migrateUrl}`,
{ telemetryMessage: "tried to use DO with service worker" }
);
}

Expand Down
14 changes: 11 additions & 3 deletions packages/wrangler/src/dev.ts
Original file line number Diff line number Diff line change
Expand Up @@ -890,7 +890,11 @@ export function getBindings(
// TODO: This error has to be a _lot_ better, ideally just asking
// to create a preview namespace for the user automatically
throw new UserError(
`In development, you should use a separate kv namespace than the one you'd use in production. Please create a new kv namespace with "wrangler kv namespace create <name> --preview" and add its id as preview_id to the kv_namespace "${binding}" in your ${configFileName(configParam.configPath)} file`
`In development, you should use a separate kv namespace than the one you'd use in production. Please create a new kv namespace with "wrangler kv namespace create <name> --preview" and add its id as preview_id to the kv_namespace "${binding}" in your ${configFileName(configParam.configPath)} file`,
{
telemetryMessage:
"no preview kv namespace configured in remote dev",
}
); // Ugh, I really don't like this message very much
}
return {
Expand Down Expand Up @@ -946,7 +950,10 @@ export function getBindings(
// same copy-on-write TODO
if (!preview_bucket_name && !local) {
throw new UserError(
`In development, you should use a separate r2 bucket than the one you'd use in production. Please create a new r2 bucket with "wrangler r2 bucket create <name>" and add its name as preview_bucket_name to the r2_buckets "${binding}" in your ${configFileName(configParam.configPath)} file`
`In development, you should use a separate r2 bucket than the one you'd use in production. Please create a new r2 bucket with "wrangler r2 bucket create <name>" and add its name as preview_bucket_name to the r2_buckets "${binding}" in your ${configFileName(configParam.configPath)} file`,
{
telemetryMessage: "no preview r2 bucket configured in remote dev",
}
);
}
return {
Expand Down Expand Up @@ -991,7 +998,8 @@ export function getBindings(
hyperdrive.localConnectionString === undefined
) {
throw new UserError(
`When developing locally, you should use a local Postgres connection string to emulate Hyperdrive functionality. Please setup Postgres locally and set the value of the 'WRANGLER_HYPERDRIVE_LOCAL_CONNECTION_STRING_${hyperdrive.binding}' variable or "${hyperdrive.binding}"'s "localConnectionString" to the Postgres connection string.`
`When developing locally, you should use a local Postgres connection string to emulate Hyperdrive functionality. Please setup Postgres locally and set the value of the 'WRANGLER_HYPERDRIVE_LOCAL_CONNECTION_STRING_${hyperdrive.binding}' variable or "${hyperdrive.binding}"'s "localConnectionString" to the Postgres connection string.`,
{ telemetryMessage: "no local hyperdrive connection string" }
);
}

Expand Down
5 changes: 4 additions & 1 deletion packages/wrangler/src/init.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,10 @@ export const init = createCommand({
} catch (err) {
if ((err as { code?: number }).code === 10090) {
throw new UserError(
"wrangler couldn't find a Worker with that name in your account.\nRun `wrangler whoami` to confirm you're logged into the correct account."
"wrangler couldn't find a Worker with that name in your account.\nRun `wrangler whoami` to confirm you're logged into the correct account.",
{
telemetryMessage: true,
}
);
}
throw err;
Expand Down
5 changes: 4 additions & 1 deletion packages/wrangler/src/package-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,10 @@ export async function getPackageManager(): Promise<PackageManager> {
return { ...PnpmPackageManager };
} else {
throw new UserError(
"Unable to find a package manager. Supported managers are: npm, yarn, and pnpm."
"Unable to find a package manager. Supported managers are: npm, yarn, and pnpm.",
{
telemetryMessage: true,
}
);
}
}
Expand Down
10 changes: 8 additions & 2 deletions packages/wrangler/src/utils/print-bindings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -777,12 +777,18 @@ export function warnOrError(
) {
if (remote === true && supports === "local") {
throw new UserError(
`${friendlyBindingNames[type]} bindings do not support accessing remote resources.`
`${friendlyBindingNames[type]} bindings do not support accessing remote resources.`,
{
telemetryMessage: true,
}
);
}
if (remote === false && supports === "remote") {
throw new UserError(
`${friendlyBindingNames[type]} bindings do not support local development. You may be able to set \`experimental_remote: true\` for the binding definition in your configuration file to access a remote version of the resource.`
`${friendlyBindingNames[type]} bindings do not support local development. You may be able to set \`experimental_remote: true\` for the binding definition in your configuration file to access a remote version of the resource.`,
{
telemetryMessage: true,
}
);
}
if (remote === undefined && supports === "remote") {
Expand Down
Loading