{"id":"61c62197c4519f60","repo":"vitest-dev/vitest","slug":"vi-dounmock-expects-a-string-path-but-received-61c621","errorCode":null,"errorMessage":"vi.doUnmock() expects a string path, but received a ${typeof path}","messagePattern":"vi\\.doUnmock\\(\\) expects a string path, but received a (.+?)","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"packages/vitest/src/integrations/vi.ts","lineNumber":711,"sourceCode":"                  importer,\n                  _mocker().getMockContext().callstack,\n                ),\n              )\n          : factory,\n      )\n\n      const rv = {} as Disposable\n      if (Symbol.dispose) {\n        rv[Symbol.dispose] = () => {\n          _mocker().queueUnmock(path, importer)\n        }\n      }\n      return rv\n    },\n\n    doUnmock(path: string | Promise<unknown>) {\n      if (typeof path !== 'string') {\n        throw new TypeError(\n          `vi.doUnmock() expects a string path, but received a ${typeof path}`,\n        )\n      }\n      const importer = getImporter('doUnmock')\n      _mocker().queueUnmock(path, importer)\n    },\n\n    async importActual<T = unknown>(path: string): Promise<T> {\n      const importer = getImporter('importActual')\n      return _mocker().importActual<T>(\n        path,\n        importer,\n        _mocker().getMockContext().callstack,\n      )\n    },\n\n    async importMock<T>(path: string): Promise<MaybeMockedDeep<T>> {\n      const importer = getImporter('importMock')","sourceCodeStart":693,"sourceCodeEnd":729,"githubUrl":"https://github.com/vitest-dev/vitest/blob/d568f8ce3739b532d5bf2c1ee1e45e8a8a473d09/packages/vitest/src/integrations/vi.ts#L693-L729","documentation":"Thrown by vi.doUnmock() when its first argument is not a string. doUnmock queues removal of a previously queued mock for a module specifier; without a concrete string path the mocker cannot match the entry to remove. Like doMock, the parameter type is permissive (`string | Promise<unknown>`) but only strings are honored at runtime.","triggerScenarios":"Calling vi.doUnmock() with undefined, an object, a number, or any non-string value. Commonly happens when the same variable used in a failed doMock is reused in doUnmock, or when destructuring a module object and passing it instead of its import path.","commonSituations":"Pairing vi.doUnmock with a dynamically-resolved module reference that is undefined; refactoring that changes a path variable type; migrating from vi.unmock (hoisted) to vi.doUnmock (not hoisted) and accidentally passing a module object.","solutions":["Pass the same string specifier you would pass to vi.doMock: vi.doUnmock('./path/to/module').","Guard the variable with a typeof check before calling doUnmock.","Use a using/await using binding returned by vi.doMock to auto-unmock instead of calling doUnmock manually."],"exampleFix":"// before\nvi.doUnmock(myModuleObject)\n// after\nvi.doUnmock('./path/to/myModule')","handlingStrategy":"type-guard","validationCode":"if (typeof path !== 'string') {\n  throw new Error('doUnmock requires a string module path')\n}\nvi.doUnmock(path)","typeGuard":"function isMockPath(path: unknown): path is string {\n  return typeof path === 'string' && path.length > 0\n}","tryCatchPattern":null,"preventionTips":["Pass the same string specifier used in the matching doMock call.","Prefer the `using` / `await using` auto-unmock binding returned by doMock over manual doUnmock."],"tags":[],"analyzedSha":"d568f8ce3739b532d5bf2c1ee1e45e8a8a473d09","analyzedAt":"2026-08-03T20:23:56.861Z","schemaVersion":2}