openclaw/openclaw · error · BrowserProfileNotFoundError

profile "${name}" not found

Error message

profile "${name}" not found

What it means

A BrowserProfileNotFoundError (HTTP 404) thrown by deleteProfile when getOwnBrowserProfile(cfg.browser?.profiles ?? {}, name) returns falsy — i.e. the profile key is not present in the runtime config's browser.profiles map. This runs after the default-profile guard, so it only fires for non-default names that are absent from config.

Source

Thrown at extensions/browser/src/browser/profiles-service.ts:244

    if (!name) {
      throw new BrowserValidationError("profile name is required");
    }
    if (!isValidProfileName(name)) {
      throw new BrowserValidationError("invalid profile name");
    }

    const state = ctx.state();
    const cfg = getRuntimeConfig();
    const profiles = cfg.browser?.profiles ?? {};
    const defaultProfile = cfg.browser?.defaultProfile ?? state.resolved.defaultProfile;
    if (name === defaultProfile) {
      throw new BrowserValidationError(
        `cannot delete the default profile "${name}"; change browser.defaultProfile first`,
      );
    }
    const runtimeProfile = getOwnBrowserProfile(profiles, name);
    if (!runtimeProfile) {
      throw new BrowserProfileNotFoundError(`profile "${name}" not found`);
    }
    const sourceProfile = getOwnBrowserProfile(
      getRuntimeConfigSourceSnapshot()?.browser?.profiles,
      name,
    );
    const expected = structuredClone(sourceProfile ?? runtimeProfile);

    let deleted = false;
    const configuredProfile = resolveProfile(resolveBrowserConfig(cfg.browser, cfg), name);
    const resolved = configuredProfile ?? state.profiles.get(name)?.profile;
    const runtime = resolved ? getOrCreateProfileRuntime(state, resolved) : undefined;

    const persistDelete = async () => {
      await deleteBrowserProfileConfig({ name, expected });
      delete state.resolved.profiles[name];
      try {
        if (resolved?.cdpIsLoopback && resolved.driver === "openclaw" && !resolved.attachOnly) {
          const userDataDir = resolveOpenClawUserDataDir(name);

View on GitHub (pinned to 01804a7531)

Solutions

  1. Refresh the profile list with listProfiles() and pass a name that is currently present.
  2. If the profile appears in the UI but not in config, run `openclaw doctor --fix` to reconcile, then retry.
  3. Treat the 404 as success if the goal is simply 'ensure it is gone' (idempotent delete).

Example fix

// before
await deleteProfile(requestedName);
// after
const names = (await listProfiles()).map(p => p.name);
if (!names.includes(requestedName)) return { ok: true, profile: requestedName, deleted: false };
await deleteProfile(requestedName);
Defensive patterns

Strategy: type-guard

Validate before calling

const live = await listProfiles();
const exists = live.some(p => p.name === name);
if (!exists) return { ok: true, profile: name, deleted: false }; // idempotent
await deleteProfile(name);

Type guard

async function profileExists(name: string): Promise<boolean> {
  return (await listProfiles()).some(p => p.name === name);
}

Try / catch

try {
  await deleteProfile(name);
} catch (e) {
  if (e instanceof BrowserProfileNotFoundError) {
    return { ok: true, profile: name, deleted: false }; // already gone
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling deleteProfile on a name that passes the format check, is not the default, but is not in cfg.browser.profiles — e.g. a stale id from a previous session, a typo, or a profile that was already deleted by another caller.

Common situations: UI showed a cached profile list that is now stale; concurrent deletion by another session; user typed a plausible-looking name that was never created; profile existed in resolved runtime state but not in source config (config-only delete path).

Related errors


AI-assisted analysis of openclaw/openclaw@01804a7531 (2026-08-12). Data as JSON: /api/errors/f812dab8c664539a. Report an issue: GitHub.