ramensoftware/windhawk · error

INVALID_REQUEST

INVALID_REQUEST

Error message

Not a valid update suppression: "${suppression}"

What it means

The webview IPC handler for setting update suppression validates the requested suppression string with isValidSuppression before applying it. An unrecognized value (e.g. a malformed version string) is rejected with code INVALID_REQUEST instead of being passed to the backend.

Solutions

  1. Print the offending value and compare it against what isValidSuppression accepts (likely a valid version string format).
  2. Fix the producer of updatesDisabledForVersion to send the expected version format.
  3. Guard in the caller: only set updatesDisabledForVersion when a valid version is available, otherwise omit the field.

Example fix

// before
const config = { updatesDisabledForVersion: version.trim().toLowerCase() };
// after
const config = semver.valid(version) ? { updatesDisabledForVersion: semver.clean(version) } : {};
Defensive patterns

Strategy: validation

Validate before calling

const suppression = config.updatesDisabledForVersion;
if (suppression !== undefined && !isValidSuppression(suppression)) {
  throw new Error(`Refusing to send invalid suppression: ${suppression}`);
}

Type guard

const isValidSuppression = (s: unknown): s is string =>
  typeof s === 'string' && /^\d+\.\d+(\.\d+)?$/.test(s);

Try / catch

try {
  await setUpdateSuppression(config);
} catch (e) {
  if (e.code === 'INVALID_REQUEST') {
    console.error('Suppression rejected:', e.message);
    resetSuppressionSetting();
  } else throw e;
}

Prevention

When it happens

Trigger: Sending a webview IPC request with config.updatesDisabledForVersion set to a value that fails isValidSuppression (undefined is allowed and means 'no suppression').

Common situations: Frontend code building the suppression string from user input or a loosely-typed version field; version format changes between components; stale/incorrect values persisted in settings.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


AI-assisted analysis of ramensoftware/windhawk@61d99ed8e1 (2026-09-12). Data as JSON: /api/errors/a6991decf159795d. Report an issue: GitHub.

Appendix: source

Thrown at src/windhawk-frontend/apps/windhawk-frontend/src/app/webviewIPC.ts:1024

  >('getModConfig', selector);
  return {
    getModConfig: result.postMessage,
    getModConfigPending: result.pending,
  };
}

export function useUpdateModConfig() {
  const selector = useCallback(
    (mockData: MockDataRegistry, request: UpdateModConfigData) => {
      // The host refuses a suppression outside the grammar, so the mock refuses
      // it too: a write no host would take must not read here as one that was.
      const suppression = request.config.updatesDisabledForVersion;
      if (suppression !== undefined && !isValidSuppression(suppression)) {
        return {
          modId: request.modId,
          succeeded: false,
          error: {
            code: 'INVALID_REQUEST',
            message: `Not a valid update suppression: "${suppression}"`,
          },
        };
      }
      return {
        modId: request.modId,
        succeeded: true,
      };
    },
    []
  );
  const result = usePostMessageWithReplyWithMock<
    UpdateModConfigData,
    UpdateModConfigReplyData
  >('updateModConfig', selector);
  return {
    updateModConfig: result.postMessage,
    updateModConfigPending: result.pending,

View on GitHub (pinned to 61d99ed8e1)