step 1: calling local:qwen3.6:35b-a3b
tool list <- {"path":"."}
tool list ok: .codecov.yml
.editorconfig
.git/
.github/
.gitignore
.mailmap
AUTHORS
CODE_OF_CONDUCT.md
History.md
LICENSE
Readme.md
__tests__/
dist/
docs/
lib/
node_modules/
package-lock.json
package.json
test-helpers/
[evidence record sha256:c51dd95ec29b525e39311d803924b9d4ba54f7a031ea46dfede9c65fa4777baf kind tool-call:list]
tool shell <- {"command":"npm run --silent test 2>&1","timeoutMs":60000}
tool shell ok: exit code: 1
stdout:
▶ app.compose
  ✔ should work with default compose  (13.091976ms)
  ✔ should work with configurable compose (1.77684ms)
✔ app.compose (15.898381ms)
▶ app.context
  ✔ should merge properties (7.47508ms)
  ✔ should not affect the original prototype (2.288831ms)
✔ app.context (10.500101ms)
▶ app.currentContext
  ✔ should get currentContext return context when asyncLocalStorage enable (9.75866ms)
  ✔ should get currentContext return undefined when asyncLocalStorage disable (2.715517ms)
  ✔ should get currentContext return context in error handler when asyncLocalStorage enable (1.486715ms)
  ✔ should get currentContext return undefined in error handler when asyncLocalStorage disable (1.553557ms)
  ✔ should support a custom asyncLocalStorage (1.867145ms)
  ▶ v8 startup snapshot
    ✔ should defer AsyncLocalStorage creation when building snapshot (0.509031ms)
    ✔ should defer with custom AsyncLocalStorage when building snapshot (0.538703ms)
    ✔ should work normally after deserialization (1.864353ms)
    ✔ should not defer when not building snapshot (0.08072ms)
  ✔ v8 startup snapshot (3.128702ms)
✔ app.currentContext (21.108093ms)
▶ app
  ✔ should handle socket errors (10.512269ms)
  ✔ should set development env when NODE_ENV missing (0.113683ms)
  ✔ should set env from the constructor (0.055966ms)
  ✔ should set proxy flag from the constructor (0.042298ms)
  ✔ should set signed cookie keys from the constructor (0.04784ms)
  ✔ should set subdomainOffset from the constructor (0.036713ms)
  ✔ should set compose from the constructor (0.048966ms)
  ✖ should have a static property exporting `HttpError` from http-errors library (0.680973ms)
✖ app (12.019571ms)
▶ app.inspect()
  ✔ should work (1.245472ms)
  ✔ should return a json representation (0.279124ms)
✔ app.inspect() (1.884856ms)
▶ app.onerror(err)
  ✔ should throw an error if a non-error is given (1.167918ms)
  ✔ should accept errors coming from other scopes (0.571416ms)
  ✔ should do nothing if status is 404 (0.213156ms)
  ✔ should do nothing if .silent (0.065634ms)
  ✔ should log the error to stderr (0.107682ms)
✔ app.onerror(err) (2.6528ms)
▶ app.request
  ✔ should merge properties (6.165433ms)
  ✔ should not affect the original prototype (1.091324ms)
✔ app.request (8.32962ms)
▶ app.respond
  ▶ when ctx.respond === false
    ✔ should function (ctx) (8.976673ms)
    ✔ should ignore set header after header sent (2.937216ms)
    ✔ should ignore set status after header sent (1.70183ms)
  ✔ when ctx.respond === false (14.057198ms)
  ▶ when this.type === null
    ✔ should not send Content-Type header (2.345547ms)
  ✔ when this.type === null (2.439644ms)
  ▶ when HEAD is used
    ✔ should not respond with the body (1.736626ms)
    ✔ should keep json headers (6.36742ms)
    ✔ should keep string headers (1.125205ms)
    ✔ should keep buffer headers (0.831537ms)
    ✔ should keep stream header if set manually (3.998286ms)
    ✔ should respond with a 404 if no body was set (1.037192ms)
    ✔ should respond with a 200 if body = "" (5.063899ms)
    ✔ should not overwrite the content-type (0.807659ms)
  ✔ when HEAD is used (21.216316ms)
  ▶ when no middleware is present
    ✔ should 404 (6.229484ms)
  ✔ when no middleware is present (6.296994ms)
  ▶ when res has already been written to
    ✔ should not cause an app error (0.879419ms)
    ✔ should send the right body (1.724916ms)
  ✔ when res has already been written to (2.682638ms)
  ▶ when .body is missing
    ▶ with status=400
      ✔ should respond with the associated status message (0.70631ms)
    ✔ with status=400 (0.746608ms)
    ▶ with status=204
      ✔ should respond without a body (0.489571ms)
    ✔ with status=204 (0.527035ms)
    ▶ with status=205
      ✔ should respond without a body (0.512407ms)
    ✔ with status=205 (0.548621ms)
    ▶ with status=304
      ✔ should respond without a body (0.433771ms)
    ✔ with status=304 (0.470901ms)
    ▶ with custom status=700
      ✔ should respond with the associated status message (0.913465ms)
    ✔ with custom status=700 (1.053694ms)
    ▶ with custom statusMessage=ok
      ✔ should respond with the custom status message (0.738065ms)
    ✔ with custom statusMessage=ok (0.780571ms)
    ▶ with custom status without message
      ✔ should respond with the status code number (0.509074ms)
    ✔ with custom status without message (0.617381ms)
  ✔ when .body is missing (4.859952ms)
  ▶ when .body is a null
    ✔ should respond 204 by default (0.69185ms)
    ✔ should respond 204 with status=200 (0.558581ms)
    ✔ should respond 205 with status=205 (0.420686ms)
    ✔ should respond 304 with status=304 (0.597795ms)
  ✔ when .body is a null (2.366883ms)
  ▶ when .body is undefined
    ✔ should respond 204 by default (0.701809ms)
    ✔ should respond 204 with status=200 (0.558539ms)
  ✔ when .body is undefined (1.330609ms)
  ▶ when .body is a string
    ✔ should respond (0.682557ms)
  ✔ when .body is a string (0.719646ms)
  ▶ when .body is a Buffer
    ✔ should respond (0.952138ms)
  ✔ when .body is a Buffer (1.013771ms)
  ▶ when .body is a Blob
    ✔ should respond (3.421286ms)
    ✔ should keep Blob headers (0.592543ms)
  ✔ when .body is a Blob (4.135389ms)
  ▶ when .body is a ReadableStream
    ✔ should respond (0.835871ms)
    ✔ should respond hello (0.807908ms)
    ✔ should handle ReadableStream with chunks (0.942387ms)
    ✔ should handle ReadableStream with custom headers (0.698018ms)
  ✔ when .body is a ReadableStream (3.39174ms)
  ▶ when .body is a Response
    ✔ should keep Response headers (2.884ms)
    ✔ should default to octet-stream (0.763652ms)
    ✔ should respond with body content (1.515303ms)
    ✔ should handle Response from fetch() with JSON (0.931802ms)
    ✔ should handle Response from fetch() with streaming body (1.155167ms)
    ✔ should handle Response from fetch() with Blob body (1.192422ms)
  ✔ when .body is a Response (8.606702ms)
  ▶ when .body is a Stream
    ✔ should respond (3.587269ms)
    ✔ should strip content-length when overwriting (1.058028ms)
    ✔ should keep content-length if not overwritten (1.723124ms)
    ✔ should keep content-length if overwritten with the same stream (3.745583ms)
    ✔ should handle errors when no content status (0.694226ms)
  ✔ when .body is a Stream (10.931622ms)
  ▶ when using pipeline for streams
    ✔ should handle stream errors when error listener exists (51.285454ms)

  Error: stream error
      at Immediate._onImmediate (/work/__tests__/application/respond.test.js:866:32)
      at process.processImmediate (node:internal/timers:574:21)


  Error: stream error
      at Immediate._onImmediate (/work/__tests__/application/respond.test.js:866:32)
      at process.processImmediate (node:internal/timers:574:21)

    ✔ should not crash when stream errors and no error listener exists (51.801361ms)
    ✔ should handle ReadableStream errors when error listener exists (51.288954ms)

  Error [ERR_STREAM_PREMATURE_CLOSE]: Premature close
      at ServerResponse.<anonymous> (node:internal/streams/pipeline:422:29)
      at ServerResponse.emit (node:events:526:24)
      at emitCloseNT (node:_http_server:1156:10)
      at Socket.onServerResponseClose (node:_http_server:292:5)
      at Socket.emit (node:events:526:24)
      at TCP.<anonymous> (node:net:362:12)

    ✔ should cleanup streams on client abort (54.473247ms)
  ✔ when using pipeline for streams (209.048087ms)
  ▶ when .body is an Object
    ✔ should respond with json (0.999144ms)
    ▶ and headers sent
      ✔ should respond with json body and headers (0.744899ms)
    ✔ and headers sent (0.995019ms)
  ✔ when .body is an Object (2.047671ms)
  ▶ when an error occurs
    ✔ should emit "error" on the app (0.952513ms)
    ▶ with an .expose property
      ✔ should expose the message (0.651219ms)
    ✔ with an .expose property (0.741857ms)

  Error: s3 explodes
      at /work/__tests__/application/respond.test.js:1026:23
      at dispatch (/work/node_modules/koa-compose/index.js:42:32)
      at /work/node_modules/koa-compose/index.js:34:12
      at Application.handleRequest (/work/lib/application.js:219:12)
      at Server.handleRequest (/work/lib/application.js:190:21)
      at Server.emit (node:events:514:28)
      at parserOnIncoming (node:_http_server:1293:12)
      at HTTPParser.parserOnHeadersComplete (node:_http_common:125:17)

    ▶ with a .status property
      ✔ should respond with .status (1.375948ms)
    ✔ with a .status property (1.426831ms)

  Error: boom!
      at /work/__tests__/application/respond.test.js:1041:15
      at dispatch (/work/node_modules/koa-compose/index.js:42:32)
      at /work/node_modules/koa-compose/index.js:34:12
      at Application.handleRequest (/work/lib/application.js:219:12)
      at Server.handleRequest (/work/lib/application.js:190:21)
      at Server.emit (node:events:514:28)
      at parserOnIncoming (node:_http_server:1293:12)
      at HTTPParser.parserOnHeadersComplete (node:_http_common:125:17)

    ✔ should respond with 500 (0.722563ms)
    ✔ should be catchable (0.563373ms)
  ✔ when an error occurs (4.50586ms)
  ▶ when status and body property
    ✔ should 200 (0.444148ms)
    ✔ should 204 (0.402225ms)
  ✔ when status and body property (0.904297ms)
  ▶ with explicit null body
    ✔ should preserve given status (0.509491ms)
    ✔ should respond with correct headers (0.632341ms)
    ✔ should return content-length equal to 0 (0.476944ms)
    ✔ should not overwrite the content-length (0.531535ms)
  ✔ with explicit null body (2.246825ms)
✔ app.respond (303.32217ms)
▶ app.response
  ✔ should merge properties (9.52121ms)
  ✔ should not affect the original prototype (1.6767ms)
  ✔ should not include status message in body for http2 (1.651405ms)
  ✔ should set ._explicitNullBody correctly (3.09203ms)
  ✔ should not set ._explicitNullBody incorrectly (8.660668ms)
  ✔ should add Content-Length when Transfer-Encoding is not defined (1.648614ms)
  ✔ should not add Content-Length when Transfer-Encoding is defined (1.82568ms)
  ✔ should not assign multiple content-type for response header (3.179752ms)
✔ app.response (32.410018ms)
▶ app.toJSON()
  ✔ should work (0.543496ms)
✔ app.toJSON() (1.611983ms)
▶ app.use(fn)
  ✔ should compose middleware (6.718096ms)
  ✔ should compose mixed middleware (1.31594ms)
  ✔ should catch thrown errors in non-async functions (1.29527ms)
  ✔ should throw error for non-function (0.454233ms)
✔ app.use(fn) (10.211184ms)
▶ ctx.assert(value, status)
  ✔ should throw an error (0.429521ms)
  ✖ should throw an error that is instanceof Koa.HttpError (0.418311ms)
  ✖ should preserve the original http-assert error (0.112891ms)
  ✔ should preserve custom error options (0.296918ms)
  ✔ should not throw when value is truthy (0.068093ms)
✖ ctx.assert(value, status) (1.723875ms)
▶ ctx.assert named methods
  ✖ ctx.assert.fail() should throw an error that is instanceof Koa.HttpError (0.186236ms)
  ✖ ctx.assert.equal() should throw an error that is instanceof Koa.HttpError (0.079386ms)
  ✖ ctx.assert.notEqual() should throw an error that is instanceof Koa.HttpError (0.077719ms)
  ✖ ctx.assert.ok() should throw an error that is instanceof Koa.HttpError (0.072885ms)
  ✖ ctx.assert.strictEqual() should throw an error that is instanceof Koa.HttpError (0.10364ms)
  ✖ ctx.assert.notStrictEqual() should throw an error that is instanceof Koa.HttpError (0.073386ms)
  ✖ ctx.assert.deepEqual() should throw an error that is instanceof Koa.HttpError (0.110391ms)
  ✖ ctx.assert.notDeepEqual() should throw an error that is instanceof Koa.HttpError (0.063217ms)
✖ ctx.assert named methods (0.924842ms)
▶ ctx.cookies
  ▶ ctx.cookies.set()
    ✔ should set an unsigned cookie (7.266258ms)
    ▶ with .signed
      ▶ when no .keys are set
        ✔ should error (3.250845ms)
      ✔ when no .keys are set (3.371196ms)
      ✔ should send a signed cookie (2.738937ms)
    ✔ with .signed (6.294701ms)
    ▶ with secure
      ✔ should get secure from request (1.833974ms)
    ✔ with secure (1.913609ms)
  ✔ ctx.cookies.set() (15.77578ms)
  ▶ ctx.cookies=
    ✔ should override cookie work (0.895046ms)
  ✔ ctx.cookies= (0.989309ms)
✔ ctx.cookies (16.925487ms)
▶ ctx.inspect()
  ✔ should return a json representation (0.774112ms)
  ✔ should not crash when called on the prototype (0.166108ms)
✔ ctx.inspect() (1.289437ms)
▶ ctx.onerror(err)
  ✔ should respond (7.706489ms)
  ✔ should unset all headers (1.729333ms)
  ✔ should set headers specified in the error (2.207819ms)
  ✔ should ignore error after headerSent (1.475838ms)

  Error: Not found
      at /work/__tests__/context/onerror.test.js:102:19
      at dispatch (/work/node_modules/koa-compose/index.js:42:32)
      at /work/node_modules/koa-compose/index.js:34:12
      at Application.handleRequest (/work/lib/application.js:219:12)
      at Server.handleRequest (/work/lib/application.js:190:21)
      at Server.emit (node:events:514:28)
      at parserOnIncoming (node:_http_server:1293:12)
      at HTTPParser.parserOnHeadersComplete (node:_http_common:125:17)

  ✔ should set status specified in the error using statusCode (1.530638ms)

  Error: some error
      at /work/__tests__/context/onerror.test.js:121:23
      at dispatch (/work/node_modules/koa-compose/index.js:42:32)
      at /work/node_modules/koa-compose/index.js:34:12
      at Application.handleRequest (/work/lib/application.js:219:12)
      at Server.handleRequest (/work/lib/application.js:190:21)
      at Server.emit (node:events:514:28)
      at parserOnIncoming (node:_http_server:1293:12)
      at HTTPParser.parserOnHeadersComplete (node:_http_common:125:17)

  ▶ when invalid err.statusCode
    ▶ not number
      ✔ should respond 500 (0.772986ms)
    ✔ not number (1.077447ms)
  ✔ when invalid err.statusCode (1.152542ms)

  Error: some error
      at /work/__tests__/context/onerror.test.js:142:23
      at dispatch (/work/node_modules/koa-compose/index.js:42:32)
      at /work/node_modules/koa-compose/index.js:34:12
      at Application.handleRequest (/work/lib/application.js:219:12)
      at Server.handleRequest (/work/lib/application.js:190:21)
      at Server.emit (node:events:514:28)
      at parserOnIncoming (node:_http_server:1293:12)
      at HTTPParser.parserOnHeadersComplete (node:_http_common:125:17)

  ▶ when invalid err.status
    ▶ not number
      ✔ should respond 500 (1.468253ms)
    ✔ not number (1.540265ms)

  Error: some error
      at /work/__tests__/context/onerror.test.js:160:23
      at dispatch (/work/node_modules/koa-compose/index.js:42:32)
      at /work/node_modules/koa-compose/index.js:34:12
      at Application.handleRequest (/work/lib/application.js:219:12)
      at Server.handleRequest (/work/lib/application.js:190:21)
      at Server.emit (node:events:514:28)
      at parserOnIncoming (node:_http_server:1293:12)
      at HTTPParser.parserOnHeadersComplete (node:_http_common:125:17)

    ▶ not http status code
      ✔ should respond 500 (1.253056ms)
    ✔ not http status code (1.331901ms)
  ✔ when invalid err.status (2.947468ms)
  ▶ when error from another scope thrown
    ✔ should handle it like a normal error (2.808781ms)
  ✔ when error from another scope thrown (2.879625ms)
  ▶ when non-error thrown
    ✔ should respond with non-error thrown message (0.957055ms)

  Error: non-error thrown: "string error"
      at Object.onerror (/work/lib/context.js:118:31)
      at onerror (/work/lib/application.js:216:34)
      at process.processTicksAndRejections (node:internal/process/task_queues:104:5)

    ✔ should use res.getHeaderNames() accessor when available (0.169858ms)
    ✔ should stringify error if it is an object (1.15375ms)
  ✔ when non-error thrown (2.365175ms)
✔ ctx.onerror(err) (24.543339ms)
▶ ctx.state
  ✔ should provide a ctx.state namespace (7.41528ms)
✔ ctx.state (7.841884ms)
Thu, 03 Sep 2026 22:09:45 GMT http-errors deprecated non-error status code; use only 4xx or 5xx status codes at lib/context.js:96:11
▶ ctx.throw(msg)
  ✔ should set .status to 500 (0.381555ms)
✔ ctx.throw(msg) (0.695684ms)
▶ ctx.throw(err)
  ✔ should set .status to 500 (0.090305ms)
✔ ctx.throw(err) (0.139687ms)
▶ ctx.throw(status, err)
  ✔ should throw the error and set .status (0.083804ms)
✔ ctx.throw(status, err) (0.124268ms)
▶ ctx.throw(status, msg)
  ✔ should throw an error (0.105974ms)
✔ ctx.throw(status, msg) (0.152397ms)
▶ ctx.throw(status)
  ✔ should throw an error (0.097473ms)
  ▶ when not valid status
    ✔ should not expose (0.540911ms)
  ✔ when not valid status (0.586084ms)
✔ ctx.throw(status) (0.914174ms)
▶ ctx.throw(status, msg, props)
  ✔ should mixin props (0.084221ms)
  ▶ when props include status
    ✔ should be ignored (0.061218ms)
  ✔ when props include status (0.08272ms)
✔ ctx.throw(status, msg, props) (0.20903ms)
▶ ctx.throw(msg, props)
  ✔ should mixin props (0.075094ms)
✔ ctx.throw(msg, props) (0.099098ms)
▶ ctx.throw(status, props)
  ✔ should mixin props (0.084763ms)
✔ ctx.throw(status, props) (0.109807ms)
▶ ctx.throw(err, props)
  ✔ should mixin props (0.055549ms)
✔ ctx.throw(err, props) (0.073677ms)
▶ ctx.toJSON()
  ✔ should return a json representation (0.811201ms)
✔ ctx.toJSON() (1.138748ms)
▶ search-params
  ▶ stringify
    ✔ Should stringify a simple object (0.501281ms)
    ✔ Should stringify an object with an array (0.080762ms)
    ✔ Should stringify an object with an array with a single value (0.130143ms)
    ✔ Stringify an object with an array with a single empty value (0.449732ms)
    ✔ Should not stringify an object with a nested object (0.10364ms)
  ✔ stringify (1.708581ms)
  ▶ parse
    ✔ Should parse a simple query string (0.306002ms)
    ✔ Should parse a query string with same key and multiple values (0.073177ms)
    ✔ Should parse a query string with an array with a single empty value (0.116226ms)
  ✔ parse (0.745108ms)
✔ search-params (2.742979ms)
▶ Load with esm
  ✔ should default export koa (44.163716ms)
  ✔ should match exports own property names (0.140937ms)
  ✔ CommonJS exports default property (0.074719ms)
  ✔ CommonJS exports default property referencing self (0.04534ms)
✔ Load with esm (44.86811ms)
▶ ctx.accept
  ✔ should return an Accept instance (0.358635ms)
✔ ctx.accept (0.710603ms)
▶ ctx.accept=
  ✔ should replace the accept object (0.554497ms)
✔ ctx.accept= (0.603171ms)
▶ ctx.accepts(types)
  ▶ with no arguments
    ▶ when Accept is populated
      ✔ should return all accepted types (1.062443ms)
    ✔ when Accept is populated (1.412408ms)
  ✔ with no arguments (1.473959ms)
  ▶ with no valid types
    ▶ when Accept is populated
      ✔ should return false (0.19061ms)
    ✔ when Accept is populated (0.25612ms)
    ▶ when Accept is not populated
      ✔ should return the first type (0.225449ms)
    ✔ when Accept is not populated (0.309586ms)
  ✔ with no valid types (1.298892ms)
  ▶ when extensions are given
    ✔ should convert to mime types (0.304627ms)
  ✔ when extensions are given (0.378887ms)
  ▶ when an array is given
    ✔ should return the first match (0.165357ms)
  ✔ when an array is given (0.209697ms)
  ▶ when multiple arguments are given
    ✔ should return the first match (0.086095ms)
  ✔ when multiple arguments are given (0.116558ms)
  ▶ when value present in Accept is an exact match
    ✔ should return the type (0.114433ms)
  ✔ when value present in Accept is an exact match (0.139853ms)
  ▶ when value present in Accept is a type match
    ✔ should return the type (0.086846ms)
  ✔ when value present in Accept is a type match (0.113807ms)
  ▶ when value present in Accept is a subtype match
    ✔ should return the type (0.189027ms)
  ✔ when value present in Accept is a subtype match (0.331422ms)
✔ ctx.accepts(types) (4.646533ms)
▶ ctx.acceptsCharsets()
  ▶ with no arguments
    ▶ when Accept-Charset is populated
      ✔ should return accepted types (0.800322ms)
    ✔ when Accept-Charset is populated (1.197378ms)
  ✔ with no arguments (1.285057ms)
  ▶ with multiple arguments
    ▶ when Accept-Charset is populated
      ▶ if any types match
        ✔ should return the best fit (0.181734ms)
      ✔ if any types match (0.259287ms)
      ▶ if no types match
        ✔ should return false (0.145604ms)
      ✔ if no types match (0.233408ms)
    ✔ when Accept-Charset is populated (0.615129ms)
    ▶ when Accept-Charset is not populated
      ✔ should return the first type (0.111516ms)
    ✔ when Accept-Charset is not populated (0.174608ms)
  ✔ with multiple arguments (0.889293ms)
  ▶ with an array
    ✔ should return the best fit (0.122392ms)
  ✔ with an array (0.167815ms)
✔ ctx.acceptsCharsets() (2.628498ms)
▶ ctx.acceptsEncodings()
  ▶ with no arguments
    ▶ when Accept-Encoding is populated
      ✔ should return accepted types (0.731437ms)
    ✔ when Accept-Encoding is populated (0.982889ms)
    ▶ when Accept-Encoding is not populated
      ✔ should return identity (0.108098ms)
    ✔ when Accept-Encoding is not populated (0.156273ms)
  ✔ with no arguments (1.282556ms)
  ▶ with multiple arguments
    ✔ should return the best fit (0.098264ms)
  ✔ with multiple arguments (0.139395ms)
  ▶ with an array
    ✔ should return the best fit (0.103973ms)
  ✔ with an array (0.354676ms)
✔ ctx.acceptsEncodings() (2.09063ms)
▶ ctx.acceptsLanguages(langs)
  ▶ with no arguments
    ▶ when Accept-Language is populated
      ✔ should return accepted types (0.7046ms)
    ✔ when Accept-Language is populated (0.963053ms)
  ✔ with no arguments (1.021186ms)
  ▶ with multiple arguments
    ▶ when Accept-Language is populated
      ▶ if any types types match
        ✔ should return the best fit (0.154814ms)
      ✔ if any types types match (0.218656ms)
      ▶ if no types match
        ✔ should return false (0.110641ms)
      ✔ if no types match (0.165024ms)
    ✔ when Accept-Language is populated (0.466233ms)
    ▶ when Accept-Language is not populated
      ✔ should return the first type (0.127059ms)
    ✔ when Accept-Language is not populated (0.201904ms)
  ✔ with multiple arguments (0.789195ms)
  ▶ with an array
    ✔ should return the best fit (0.109641ms)
  ✔ with an array (0.144563ms)
✔ ctx.acceptsLanguages(langs) (2.152555ms)
▶ req.charset
  ▶ with no content-type present
    ✔ should return "" (0.467066ms)
  ✔ with no content-type present (0.723435ms)
  ▶ with charset present
    ✔ should return "" (0.114766ms)
  ✔ with charset present (0.160814ms)
  ▶ with a charset
    ✔ should return the charset (0.162315ms)
    ✔ should return "" if content-type is invalid (0.064675ms)
  ✔ with a charset (0.297042ms)
✔ req.charset (1.382737ms)
▶ ctx.fresh
  ▶ the request method is not GET and HEAD
    ✔ should return false (0.375554ms)
  ✔ the request method is not GET and HEAD (0.732145ms)
  ▶ the response is non-2xx
    ✔ should return false (0.149188ms)
  ✔ the response is non-2xx (0.195361ms)
  ▶ the response is 2xx
    ▶ and etag matches
      ✔ should return true (0.110724ms)
    ✔ and etag matches (0.154564ms)
    ▶ and etag does not match
      ✔ should return false (0.219448ms)
    ✔ and etag does not match (0.612878ms)
  ✔ the response is 2xx (0.850662ms)
✔ ctx.fresh (2.151805ms)
▶ ctx.get(name)
  ✔ should return the field value (0.347132ms)
✔ ctx.get(name) (0.658677ms)
▶ req.header
  ✔ should return the request header object (1.000433ms)
  ✔ should set the request header object (0.195361ms)
✔ req.header (1.566889ms)
▶ req.headers
  ✔ should return the request header object (0.449188ms)
  ✔ should set the request header object (0.093389ms)
✔ req.headers (0.947051ms)
▶ req.host
  ✔ should return host with port (0.408516ms)
  ▶ with no host present
    ✔ should return "" (0.094764ms)
  ✔ with no host present (0.172983ms)
  ▶ when less then HTTP/2
    ✔ should not use :authority header (0.082304ms)
  ✔ when less then HTTP/2 (0.130769ms)
  ▶ when HTTP/2
    ✔ should use :authority header (0.093388ms)
    ✔ should use host header as fallback (0.066426ms)
  ✔ when HTTP/2 (0.227574ms)
  ▶ when X-Forwarded-Host is present
    ▶ and proxy is not trusted
      ✔ should be ignored on HTTP/1 (0.077469ms)
      ✔ should be ignored on HTTP/2 (0.293916ms)
    ✔ and proxy is not trusted (0.441396ms)
    ▶ and proxy is trusted
      ✔ should be used on HTTP/1 (0.089471ms)
      ✔ should be used on HTTP/2 (0.205904ms)
    ✔ and proxy is trusted (0.340632ms)
  ✔ when X-Forwarded-Host is present (0.88675ms)
  ▶ with Host header containing @
    ✔ should correctly parse host from userinfo@host format (0.233783ms)
    ✔ should correctly parse host from user@host format (0.054675ms)
    ✔ should correctly parse host with port from userinfo@host:port format (0.042798ms)
    ✔ should correctly parse @ in X-Forwarded-Host when proxy is trusted (0.09393ms)
    ✔ should correctly parse @ in :authority on HTTP/2 (0.077261ms)
    ✔ should return empty string for invalid host with @ (0.062717ms)
  ✔ with Host header containing @ (0.637007ms)
✔ req.host (2.922206ms)
▶ req.hostname
  ✔ should return hostname void of port (0.405474ms)
  ▶ with no host present
    ✔ should return "" (0.078345ms)
  ✔ with no host present (0.13952ms)
  ▶ with IPv6 in host
    ✔ should parse localhost void of port (0.135269ms)
    ✔ should parse localhost with port 80 (0.060967ms)
    ✔ should parse localhost with non-special schema port (0.076802ms)
    ✔ should reduce IPv6 with non-special schema port as hostname (0.122892ms)
    ✔ should return empty string when invalid (0.083428ms)
  ✔ with IPv6 in host (0.782653ms)
  ▶ when X-Forwarded-Host is present
    ▶ and proxy is not trusted
      ✔ should be ignored (0.071636ms)
    ✔ and proxy is not trusted (0.118308ms)
    ▶ and proxy is trusted
      ✔ should be used (0.068843ms)
    ✔ and proxy is trusted (0.108223ms)
  ✔ when X-Forwarded-Host is present (0.298293ms)
  ▶ with Host header containing @
    ✔ should correctly parse hostname from userinfo@host format (0.104598ms)
    ✔ should correctly parse hostname from user@host format (0.075969ms)
    ✔ should correctly parse hostname with port from userinfo@host:port format (0.059091ms)
    ✔ should correctly parse @ in X-Forwarded-Host when proxy is trusted (0.046173ms)
  ✔ with Host header containing @ (0.333547ms)
✔ req.hostname (2.365044ms)
▶ ctx.href
  ✔ should return the full request url (0.440938ms)
  ✔ should work with `GET http://example.com/foo` (6.33494ms)
✔ ctx.href (7.236026ms)
▶ ctx.idempotent
  ▶ when the request method is idempotent
    ✔ should return true (0.43927ms)
  ✔ when the request method is idempotent (0.702182ms)
  ▶ when the request method is not idempotent
    ✔ should return false (0.075636ms)
  ✔ when the request method is not idempotent (0.118642ms)
✔ ctx.idempotent (0.996474ms)
▶ req.inspect()
  ▶ with no request.req present
    ✔ should return null (0.467649ms)
  ✔ with no request.req present (0.783028ms)
  ✔ should return a json representation (0.491362ms)
✔ req.inspect() (1.467208ms)
▶ req.ip
  ▶ with req.ips present
    ✔ should return req.ips[0] (0.372552ms)
  ✔ with req.ips present (0.638758ms)
  ▶ with no req.ips present
    ✔ should return req.socket.remoteAddress (0.105306ms)
    ▶ with req.socket.remoteAddress not present
      ✔ should return an empty string (0.09518ms)
    ✔ with req.socket.remoteAddress not present (0.139061ms)
  ✔ with no req.ips present (0.32017ms)
  ✔ should be lazy inited and cached (0.060092ms)
  ✔ should reset ip work (0.069426ms)
✔ req.ip (1.318311ms)
▶ req.ips
  ▶ when X-Forwarded-For is present
    ▶ and proxy is not trusted
      ✔ should be ignored (0.60346ms)
    ✔ and proxy is not trusted (0.915838ms)
    ▶ and proxy is trusted
      ✔ should be used (0.134645ms)
    ✔ and proxy is trusted (0.190152ms)
  ✔ when X-Forwarded-For is present (1.252636ms)
  ▶ when options.proxyIpHeader is present
    ▶ and proxy is not trusted
      ✔ should be ignored (0.097472ms)
    ✔ and proxy is not trusted (0.158564ms)
    ▶ and proxy is trusted
      ✔ should be used (0.28975ms)
    ✔ and proxy is trusted (0.426018ms)
  ✔ when options.proxyIpHeader is present (0.734771ms)
  ▶ when options.maxIpsCount is present
    ▶ and proxy is not trusted
      ✔ should be ignored (0.234283ms)
    ✔ and proxy is not trusted (0.270164ms)
    ▶ and proxy is trusted
      ✔ should be used (0.236909ms)
    ✔ and proxy is trusted (0.263287ms)
  ✔ when options.maxIpsCount is present (0.589751ms)
✔ req.ips (2.754974ms)
▶ ctx.is(type)
  ✔ should ignore params (0.507113ms)
  ▶ when no body is given
    ✔ should return null (0.081803ms)
  ✔ when no body is given (0.140354ms)
  ▶ when no content type is given
    ✔ should return false (0.075594ms)
  ✔ when no content type is given (0.118933ms)
  ▶ give no types
    ✔ should return the mime type (0.218989ms)
  ✔ give no types (0.260703ms)
  ▶ given one type
    ✔ should return the type or false (0.138269ms)
  ✔ given one type (0.201445ms)
  ▶ given multiple types
    ✔ should return the first match or false (0.126726ms)
  ✔ given multiple types (0.178526ms)
  ▶ when Content-Type: application/x-www-form-urlencoded
    ✔ should match "urlencoded" (0.072551ms)
  ✔ when Content-Type: application/x-www-form-urlencoded (0.125809ms)
✔ ctx.is(type) (1.990199ms)
▶ ctx.length
  ✔ should return length in content-length (0.442105ms)
  ✔ should return undefined with no content-length present (0.075886ms)
  ✔ should handle zero content-length (0.058842ms)
  ✔ should handle Content-Length > 2GB (2147483648) (0.092388ms)
  ✔ should handle very large Content-Length (10GB) (0.069885ms)
  ✔ should handle floating-point-like strings (truncate decimal) (0.060009ms)
  ✔ should return undefined for non-numeric strings (0.048299ms)
  ✔ should return undefined for empty string (0.054508ms)
✔ ctx.length (1.394072ms)
▶ ctx.origin
  ✔ should return the origin of url (0.350966ms)
✔ ctx.origin (0.668803ms)
▶ ctx.path
  ✔ should return the pathname (0.854621ms)
✔ ctx.path (1.183751ms)
▶ ctx.path=
  ✔ should set the pathname (0.113891ms)
  ✔ should change .url but not .originalUrl (0.067551ms)
  ✔ should not affect parseurl (0.058216ms)
✔ ctx.path= (0.322212ms)
▶ req.protocol
  ▶ when encrypted
    ✔ should return "https" (0.343966ms)
  ✔ when encrypted (0.608128ms)
  ▶ when unencrypted
    ✔ should return "http" (0.083053ms)
  ✔ when unencrypted (0.175483ms)
  ▶ when X-Forwarded-Proto is set
    ▶ and proxy is trusted
      ✔ should be used (0.104348ms)
      ▶ and X-Forwarded-Proto is empty
        ✔ should return "http" (0.084429ms)
      ✔ and X-Forwarded-Proto is empty (0.211239ms)
    ✔ and proxy is trusted (0.379804ms)
    ▶ and proxy is not trusted
      ✔ should not be used (0.354509ms)
    ✔ and proxy is not trusted (0.405474ms)
  ✔ when X-Forwarded-Proto is set (0.864914ms)
✔ req.protocol (1.844053ms)
▶ ctx.query
  ▶ when missing
    ✔ should return an empty object (0.407725ms)
    ✔ should return the same object each time it's accessed (0.09818ms)
  ✔ when missing (0.790737ms)
  ✔ should return a parsed query string (0.077261ms)
✔ ctx.query (1.032646ms)
▶ ctx.query=
  ✔ should stringify and replace the query string and search (0.14998ms)
  ✔ should change .url but not .originalUrl (0.077428ms)
✔ ctx.query= (0.288124ms)
▶ ctx.querystring
  ✔ should return the querystring (0.392806ms)
  ▶ when ctx.req not present
    ✔ should return an empty string (0.082761ms)
  ✔ when ctx.req not present (0.139103ms)
✔ ctx.querystring (0.973763ms)
▶ ctx.querystring=
  ✔ should replace the querystring (0.110849ms)
  ✔ should update ctx.search and ctx.query (0.102681ms)
  ✔ should change .url but not .originalUrl (0.064509ms)
  ✔ should not affect parseurl (0.069552ms)
✔ ctx.querystring= (0.897919ms)
▶ ctx.search=
  ✔ should replace the search (0.419643ms)
  ✔ should update ctx.querystring and ctx.query (0.117933ms)
  ✔ should change .url but not .originalUrl (0.065635ms)
  ▶ when missing
    ✔ should return "" (0.065342ms)
  ✔ when missing (0.120351ms)
✔ ctx.search= (1.111741ms)
▶ req.secure
  ✔ should return true when encrypted (0.346757ms)
✔ req.secure (0.662927ms)
▶ req.stale
  ✔ should be the inverse of req.fresh (0.990141ms)
✔ req.stale (1.317686ms)
▶ req.subdomains
  ✔ should return subdomain array (3.370978ms)
  ✔ should work with no host present (0.096431ms)
  ✔ should check if the host is an ip address, even with a port (0.068301ms)
✔ req.subdomains (3.943517ms)
▶ req.type
  ✔ should return type void of parameters (0.360051ms)
  ✔ should return empty string with no host present (0.081428ms)
✔ req.type (0.790487ms)
▶ req.URL
  ✔ should not throw when host is void (0.393598ms)
  ✔ should not throw when header.host is invalid (0.540494ms)
  ✔ should return empty object when invalid (0.283124ms)
✔ req.URL (1.603935ms)
▶ ctx.append(name, val)
  ✔ should append multiple headers (0.606211ms)
  ✔ should accept array of values (0.095472ms)
  ✔ should get reset by res.set(field, val) (0.076261ms)
  ✔ should work with res.set(field, val) first (0.066384ms)
✔ ctx.append(name, val) (1.234425ms)
▶ ctx.attachment([filename])
  ▶ security: prevent Content-Type override (GHSA-c5vw-j4hf-j526)
    ✔ should NOT override Content-Type when already set (0.535075ms)
    ✔ should preserve safe Content-Type for SVG files (0.1206ms)
    ✔ should set Content-Type when not previously set (0.208321ms)
  ✔ security: prevent Content-Type override (GHSA-c5vw-j4hf-j526) (1.246093ms)
  ▶ when given a filename
    ✔ should set the filename param (0.110974ms)
  ✔ when given a filename (0.158397ms)
  ▶ when omitting filename
    ✔ should not set filename param (0.401974ms)
  ✔ when omitting filename (0.483318ms)
  ▶ when given a non-ascii filename
    ✔ should set the encodeURI filename param (0.150188ms)
    ✔ should work with http client (14.945619ms)
  ✔ when given a non-ascii filename (15.319214ms)
✔ ctx.attachment([filename]) (17.446724ms)
▶ contentDisposition(filename, options)
  ▶ with "fallback" option
    ✔ should require a string or Boolean (0.223573ms)
    ✔ should default to true (0.192569ms)
    ▶ when "false"
      ✔ should not generate ISO-8859-1 fallback (0.141979ms)
      ✔ should keep ISO-8859-1 filename (0.062384ms)
    ✔ when "false" (0.274998ms)
    ▶ when "true"
      ✔ should generate ISO-8859-1 fallback (0.066468ms)
      ✔ should pass through ISO-8859-1 filename (0.048674ms)
    ✔ when "true" (0.144604ms)
    ▶ when a string
      ✔ should require an ISO-8859-1 string (0.096639ms)
      ✔ should use as ISO-8859-1 fallback (0.04659ms)
      ✔ should use as fallback even when filename is ISO-8859-1 (0.158939ms)
      ✔ should do nothing if equal to filename (0.126768ms)
      ✔ should use the basename of the string (0.044882ms)
      ✔ should do nothing without filename option (0.036963ms)
    ✔ when a string (0.571623ms)
  ✔ with "fallback" option (1.5811ms)
  ▶ with "type" option
    ✔ should default to attachment (0.0583ms)
    ✔ should require a string (0.048132ms)
    ✔ should require a valid type (0.040631ms)
    ✔ should create a header with inline type (0.032713ms)
    ✔ should create a header with inline type and filename (0.040339ms)
    ✔ should normalize type (0.033754ms)
  ✔ with "type" option (0.317878ms)
✔ contentDisposition(filename, options) (2.026579ms)
▶ ctx.back([alt])
  ✔ should redirect to Referrer (0.726645ms)
  ✔ should redirect to the same origin referrer (0.128435ms)
  ✔ should redirect to root if the same origin referrer is not present (0.096889ms)
  ✔ should redirect to Referer to a relative path (0.089179ms)
  ✔ should redirect to Referer to a same origin url (0.102681ms)
  ✔ should default to alt (0.139603ms)
  ✔ should default redirect to / (0.104806ms)
  ✔ should fix Trailing Double-Slash security issue (0.122893ms)
✔ ctx.back([alt]) (1.98749ms)
▶ res.body=
  ▶ when Content-Type is set
    ✔ should not override (0.791362ms)
    ▶ when body is an object
      ✔ should override as json (7.979965ms)
    ✔ when body is an object (8.093606ms)
    ✔ should override length (0.15698ms)
  ✔ when Content-Type is set (9.445673ms)
  ▶ when a string is given
    ✔ should default to text (0.124393ms)
    ✔ should set length (0.236075ms)
    ▶ and contains a non-leading <
      ✔ should default to text (0.126477ms)
    ✔ and contains a non-leading < (0.200946ms)
  ✔ when a string is given (0.683139ms)
  ▶ when an html string is given
    ✔ should default to html (0.094097ms)
    ✔ should set length (0.116558ms)
    ✔ should set length when body is overridden (0.089054ms)
    ▶ when it contains leading whitespace
      ✔ should default to html (0.137561ms)
    ✔ when it contains leading whitespace (0.163107ms)
  ✔ when an html string is given (0.567831ms)
  ▶ when an xml string is given
    ✔ should default to html (0.100348ms)
  ✔ when an xml string is given (0.13156ms)
  ▶ when a stream is given
    ✔ should default to an octet stream (0.207988ms)
    ✔ should support custom stream (0.06926ms)
    ✔ should not add error handler to stream (handled by pipeline) (0.095555ms)
    ✔ should NOT cleanup original stream when replaced by new stream (to support wrapping middleware) (0.076303ms)
    ✔ should cleanup original stream when replaced by null (0.168524ms)
    ✔ should not throw unhandled errors when replacing failing stream (11.435997ms)
    ✔ should handle multiple sequential stream replacements (0.157564ms)
    ✔ should handle four sequential stream replacements (0.078302ms)
    ✔ should cleanup stream when replaced by string (0.068801ms)
    ✔ should cleanup stream when replaced by buffer (0.100639ms)
    ✔ should cleanup stream when replaced by object (0.082429ms)
    ✔ should support wrapping stream middleware (like koa-compress) (0.676471ms)
  ✔ when a stream is given (13.391232ms)
  ▶ when a buffer is given
    ✔ should default to an octet stream (0.065467ms)
    ✔ should set length (0.041214ms)
  ✔ when a buffer is given (0.139811ms)
  ▶ when an object is given
    ✔ should default to json (0.088971ms)
  ✔ when an object is given (0.113183ms)
  ▶ when a ReadableStream is given
    ✔ should default to an octet stream (0.191902ms)
  ✔ when a ReadableStream is given (0.210905ms)
  ▶ when a Blob is given
    ✔ should default to an octet stream (0.349633ms)
    ✔ should set length (0.13877ms)
  ✔ when a Blob is given (0.528909ms)
  ▶ when a response is given
    ✔ should set the status (0.493111ms)
    ✔ should set headers (0.26237ms)
    ✔ should redirect (0.151397ms)
  ✔ when a response is given (0.964595ms)
✔ res.body= (26.590812ms)
▶ res.etag=
  ✔ should not modify an etag with quotes (0.857538ms)
  ✔ should not modify a weak etag (0.13427ms)
  ✔ should add quotes around an etag if necessary (0.063218ms)
✔ res.etag= (1.43412ms)
▶ res.etag
  ✔ should return etag (0.074552ms)
✔ res.etag (0.12235ms)
▶ ctx.flushHeaders()
  ✔ should set headersSent (7.188186ms)
  ✔ should allow a response afterwards (1.565805ms)
  ✔ should send the correct status code (2.113216ms)
  ✔ should ignore set header after flushHeaders (2.049915ms)
  ✔ should flush headers first and delay to send data (16.532094ms)
  ✔ should catch stream error (3.452656ms)
✔ ctx.flushHeaders() (33.497208ms)
▶ ctx.get(name)
  ✔ should get a field value, case insensitive (0.51424ms)
  ✔ should have the same behavior as ctx.res.getHeader on undefined and null values (0.090263ms)
  ✔ should not convert header value type (0.102473ms)
  ✔ should return undefined for non-existent headers (0.06005ms)
✔ ctx.get(name) (1.151497ms)
▶ ctx.response.has(name)
  ✔ should check a field value, case insensitive way (0.388513ms)
  ✔ should return false for non-existent header (0.085846ms)
✔ ctx.response.has(name) (0.824159ms)
▶ res.header
  ✔ should return the response header object (0.603628ms)
  ✔ should use res.getHeaders() accessor when available (0.147104ms)
  ✔ should return the response header object when no mocks are in use (8.171597ms)
  ▶ when res._headers not present
    ✔ should return empty object (0.19186ms)
  ✔ when res._headers not present (0.291415ms)
✔ res.header (9.72094ms)
▶ res.header
  ✔ should return the response header object (0.696099ms)
  ▶ when res._headers not present
    ✔ should return empty object (0.114099ms)
  ✔ when res._headers not present (0.183526ms)
✔ res.header (1.914647ms)
▶ res.inspect()
  ▶ with no response.res present
    ✔ should return null (0.545076ms)
  ✔ with no response.res present (0.827407ms)
  ✔ should return a json representation (0.452646ms)
✔ res.inspect() (2.001153ms)
▶ response.is(type)
  ✔ should ignore params (0.537284ms)
  ▶ when no type is set
    ✔ should return false (0.083345ms)
  ✔ when no type is set (0.146062ms)
  ▶ when given no types
    ✔ should return the type (0.106806ms)
  ✔ when given no types (0.153063ms)
  ▶ given one type
    ✔ should return the type or false (0.169774ms)
  ✔ given one type (0.215614ms)
  ▶ given multiple types
    ✔ should return the first match or false (0.143853ms)
  ✔ given multiple types (0.205654ms)
  ▶ when Content-Type: application/x-www-form-urlencoded
    ✔ should match "urlencoded" (0.397222ms)
  ✔ when Content-Type: application/x-www-form-urlencoded (0.450646ms)
✔ response.is(type) (2.207932ms)
▶ res.lastModified
  ✔ should set the header as a UTCString (0.485484ms)
  ✔ should work with date strings (0.098222ms)
  ✔ should get the header as a Date (0.081595ms)
  ▶ when lastModified not set
    ✔ should get undefined (0.068676ms)
  ✔ when lastModified not set (0.127893ms)
✔ res.lastModified (1.277344ms)
▶ res.length
  ▶ when Content-Length is defined
    ✔ should return a number (0.396597ms)
    ▶ but not number
      ✔ should return 0 (0.08597ms)
    ✔ but not number (0.151521ms)
  ✔ when Content-Length is defined (0.826115ms)
  ▶ when Content-Length is not defined
    ▶ and a .body is set
      ✔ should return a number (6.349883ms)
    ✔ and a .body is set (6.422226ms)
    ▶ and .body is not
      ✔ should return undefined (0.6005ms)
    ✔ and .body is not (0.718642ms)
  ✔ when Content-Length is not defined (7.399863ms)
  ▶ and a .type is set to json
    ▶ and a .body is set to null
      ✔ should return a number (0.131894ms)
    ✔ and a .body is set to null (0.187443ms)
  ✔ and a .type is set to json (0.245076ms)
✔ res.length (8.672873ms)
▶ res.message
  ✔ should return the response status message (1.131282ms)
  ▶ when res.message not present
    ✔ should look up in statuses (0.094388ms)
  ✔ when res.message not present (0.157647ms)
✔ res.message (1.655314ms)
▶ res.message=
  ✔ should set response status message (0.106181ms)
✔ res.message= (0.160439ms)
▶ ctx.redirect(url)
  ✔ should redirect to the given url (0.708848ms)
  ✔ should formatting url before redirect (0.129268ms)
  ✔ should formatting url before redirect (0.092221ms)
  ✔ should auto fix not encode url (9.551287ms)
  ▶ when html is accepted
    ✔ should respond with html (0.412974ms)
    ✔ should escape the url (0.253327ms)
  ✔ when html is accepted (0.768773ms)
  ▶ when text is accepted
    ✔ should respond with text (0.150521ms)
  ✔ when text is accepted (0.235866ms)
  ▶ when status is 301
    ✔ should not change the status code (0.157189ms)
  ✔ when status is 301 (0.231449ms)
  ▶ when status is 304
    ✔ should change the status code (0.134893ms)
  ✔ when status is 304 (0.180525ms)
  ▶ when content-type was present
    ✔ should overwrite content-type (4.915517ms)
  ✔ when content-type was present (4.94698ms)
✔ ctx.redirect(url) (17.390543ms)
▶ ctx.remove(name)
  ✔ should remove a field (0.540492ms)
✔ ctx.remove(name) (0.851535ms)
▶ ctx.set(name, val)
  ✔ should set a field value (0.361092ms)
  ✔ should coerce number to string (0.135894ms)
  ✔ should coerce undefined to string (0.065301ms)
  ✔ should set a field value of array (0.285331ms)
✔ ctx.set(name, val) (1.721031ms)
▶ ctx.set(object)
  ✔ should set multiple fields (0.077219ms)
✔ ctx.set(object) (0.121392ms)
▶ res.socket
  ✔ should return the request socket object (0.466689ms)
✔ res.socket (0.863661ms)
▶ res.status=
  ▶ when a status code
    ▶ and valid
      ✔ should set the status (0.397764ms)
      ✔ should not throw (0.077219ms)
    ✔ and valid (0.747979ms)
    ▶ and invalid
      ✔ should throw (0.63763ms)
    ✔ and invalid (0.691888ms)
    ▶ and custom status
      ✔ should set the status (1.459453ms)
      ✔ should not throw (0.198028ms)
    ✔ and custom status (1.752118ms)
    ▶ and HTTP/2
      ✔ should not set the status message (0.109473ms)
    ✔ and HTTP/2 (0.162023ms)
  ✔ when a status code (3.615877ms)
  ▶ when a status string
    ✔ should throw (0.114307ms)
  ✔ when a status string (0.157188ms)
  ▶ when 204
    ✔ should strip content related header fields (13.687404ms)
    ✔ should strip content related header fields after status set (3.785818ms)
  ✔ when 204 (17.56811ms)
  ▶ when 205
    ✔ should strip content related header fields (1.046229ms)
    ✔ should strip content related header fields after status set (0.896541ms)
  ✔ when 205 (2.016573ms)
  ▶ when 304
    ✔ should strip content related header fields (1.292096ms)
    ✔ should strip content related header fields after status set (0.655799ms)
  ✔ when 304 (2.012488ms)
✔ res.status= (25.607853ms)
▶ ctx.type=
  ▶ with a mime
    ✔ should set the Content-Type (0.435394ms)
  ✔ with a mime (0.698223ms)
  ▶ with an extension
    ✔ should lookup the mime (0.132768ms)
  ✔ with an extension (0.186943ms)
  ▶ without a charset
    ✔ should default the charset (0.105431ms)
  ✔ without a charset (0.15198ms)
  ▶ with a charset
    ✔ should not default the charset (0.090305ms)
  ✔ with a charset (0.137603ms)
  ▶ with an unknown extension
    ✔ should not set a content-type (0.139853ms)
  ✔ with an unknown extension (0.222406ms)
✔ ctx.type= (1.727199ms)
▶ ctx.type
  ▶ with no Content-Type
    ✔ should return "" (0.079802ms)
  ✔ with no Content-Type (0.145062ms)
  ▶ with a Content-Type
    ✔ should return the mime (0.069385ms)
  ✔ with a Content-Type (0.09693ms)
  ▶ when setting to +json content type
    ✔ should set the content type to json (0.06405ms)
  ✔ when setting to +json content type (0.087471ms)
✔ ctx.type (0.444603ms)
▶ ctx.vary(field)
  ▶ when Vary is not set
    ✔ should set it (0.422517ms)
  ✔ when Vary is not set (0.687554ms)
  ▶ when Vary is set
    ✔ should append (0.140186ms)
  ✔ when Vary is set (0.193527ms)
  ▶ when Vary already contains the value
    ✔ should not append (0.089512ms)
  ✔ when Vary already contains the value (0.137685ms)
✔ ctx.vary(field) (1.226379ms)
▶ res.writable
  ▶ when continuous requests in one persistent connection
    ✔ should always be writable and respond to all requests (9.042299ms)
  ✔ when continuous requests in one persistent connection (9.352676ms)
  ▶ when socket closed before response sent
    ✔ should not be writable (5.102043ms)
  ✔ when socket closed before response sent (5.214808ms)
  ▶ when response finished
    ✔ should not be writable (6.153981ms)
  ✔ when response finished (6.264705ms)
✔ res.writable (21.050302ms)
ℹ tests 452
ℹ suites 287
ℹ pass 441
ℹ fail 11
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 2234.351609

✖ failing tests:

test at __tests__/application/index.test.js:76:3
✖ should have a static property exporting `HttpError` from http-errors library (0.680973ms)
  TypeError: cannot construct abstract class
      at Object.HttpError (/work/node_modules/http-errors/index.js:114:11)
      at expectedException (node:assert:578:17)
      at expectsError (node:assert:703:21)
      at strict.throws (node:assert:759:3)
      at TestContext.<anonymous> (/work/__tests__/application/index.test.js:81:12)
      at Test.runInAsyncScope (node:async_hooks:227:14)
      at Test.run (node:internal/test_runner/test:1397:25)
      at Suite.processPendingSubtests (node:internal/test_runner/test:969:18)
      at Test.postRun (node:internal/test_runner/test:1537:19)
      at Test.run (node:internal/test_runner/test:1462:12)

test at __tests__/context/assert.test.js:51:3
✖ should throw an error that is instanceof Koa.HttpError (0.418311ms)
  AssertionError [ERR_ASSERTION]: Expected values to be strictly equal:
  
  false !== true
  
      at TestContext.<anonymous> (/work/__tests__/context/assert.test.js:55:12)
      at Test.runInAsyncScope (node:async_hooks:227:14)
      at Test.run (node:internal/test_runner/test:1397:25)
      at Suite.processPendingSubtests (node:internal/test_runner/test:969:18)
      at Test.postRun (node:internal/test_runner/test:1537:19)
      at Test.run (node:internal/test_runner/test:1462:12)
      at async Promise.all (index 0)
      at async Suite.run (node:internal/test_runner/test:1889:7)
      at async startSubtestAfterBootstrap (node:internal/test_runner/harness:387:3) {
    generatedMessage: true,
    code: 'ERR_ASSERTION',
    actual: false,
    expected: true,
    operator: 'strictEqual',
    diff: 'simple'
  }

test at __tests__/context/assert.test.js:63:3
✖ should preserve the original http-assert error (0.112891ms)
  AssertionError [ERR_ASSERTION]: Expected values to be strictly equal:
  
  false !== true
  
      at TestContext.<anonymous> (/work/__tests__/context/assert.test.js:70:12)
      at Test.runInAsyncScope (node:async_hooks:227:14)
      at Test.run (node:internal/test_runner/test:1397:25)
      at Suite.processPendingSubtests (node:internal/test_runner/test:969:18)
      at Test.postRun (node:internal/test_runner/test:1537:19)
      at Test.run (node:internal/test_runner/test:1462:12)
      at async Suite.processPendingSubtests (node:internal/test_runner/test:969:7) {
    generatedMessage: true,
    code: 'ERR_ASSERTION',
    actual: false,
    expected: true,
    operator: 'strictEqual',
    diff: 'simple'
  }

test at __tests__/context/assert.test.js:101:5
✖ ctx.assert.fail() should throw an error that is instanceof Koa.HttpError (0.186236ms)
  AssertionError [ERR_ASSERTION]: Expected values to be strictly equal:
  
  false !== true
  
      at TestContext.<anonymous> (/work/__tests__/context/assert.test.js:105:14)
      at Test.runInAsyncScope (node:async_hooks:227:14)
      at Test.run (node:internal/test_runner/test:1397:25)
      at Test.start (node:internal/test_runner/test:1257:17)
      at node:internal/test_runner/test:1887:71
      at node:internal/per_context/primordials:504:82
      at new Promise (<anonymous>)
      at new SafePromise (node:internal/per_context/primordials:478:3)
      at node:internal/per_context/primordials:504:9
      at Array.map (<anonymous>) {
    generatedMessage: true,
    code: 'ERR_ASSERTION',
    actual: false,
    expected: true,
    operator: 'strictEqual',
    diff: 'simple'
  }

test at __tests__/context/assert.test.js:101:5
✖ ctx.assert.equal() should throw an error that is instanceof Koa.HttpError (0.079386ms)
  AssertionError [ERR_ASSERTION]: Expected values to be strictly equal:
  
  false !== true
  
      at TestContext.<anonymous> (/work/__tests__/context/assert.test.js:105:14)
      at Test.runInAsyncScope (node:async_hooks:227:14)
      at Test.run (node:internal/test_runner/test:1397:25)
      at Suite.processPendingSubtests (node:internal/test_runner/test:969:18)
      at Test.postRun (node:internal/test_runner/test:1537:19)
      at Test.run (node:internal/test_runner/test:1462:12)
      at async Promise.all (index 0)
      at async Suite.run (node:internal/test_runner/test:1889:7)
      at async Test.processPendingSubtests (node:internal/test_runner/test:969:7) {
    generatedMessage: true,
    code: 'ERR_ASSERTION',
    actual: false,
    expected: true,
    operator: 'strictEqual',
    diff: 'simple'
  }

test at __tests__/context/assert.test.js:101:5
✖ ctx.assert.notEqual() should throw an error that is instanceof Koa.HttpError (0.077719ms)
  AssertionError [ERR_ASSERTION]: Expected values to be strictly equal:
  
  false !== true
  
      at TestContext.<anonymous> (/work/__tests__/context/assert.test.js:105:14)
      at Test.runInAsyncScope (node:async_hooks:227:14)
      at Test.run (node:internal/test_runner/test:1397:25)
      at Suite.processPendingSubtests (node:internal/test_runner/test:969:18)
      at Test.postRun (node:internal/test_runner/test:1537:19)
      at Test.run (node:internal/test_runner/test:1462:12)
      at async Suite.processPendingSubtests (node:internal/test_runner/test:969:7) {
    generatedMessage: true,
    code: 'ERR_ASSERTION',
    actual: false,
    expected: true,
    operator: 'strictEqual',
    diff: 'simple'
  }

test at __tests__/context/assert.test.js:101:5
✖ ctx.assert.ok() should throw an error that is instanceof Koa.HttpError (0.072885ms)
  AssertionError [ERR_ASSERTION]: Expected values to be strictly equal:
  
  false !== true
  
      at TestContext.<anonymous> (/work/__tests__/context/assert.test.js:105:14)
      at Test.runInAsyncScope (node:async_hooks:227:14)
      at Test.run (node:internal/test_runner/test:1397:25)
      at Suite.processPendingSubtests (node:internal/test_runner/test:969:18)
      at Test.postRun (node:internal/test_runner/test:1537:19)
      at Test.run (node:internal/test_runner/test:1462:12)
      at async Suite.processPendingSubtests (node:internal/test_runner/test:969:7) {
    generatedMessage: true,
    code: 'ERR_ASSERTION',
    actual: false,
    expected: true,
    operator: 'strictEqual',
    diff: 'simple'
  }

test at __tests__/context/assert.test.js:101:5
✖ ctx.assert.strictEqual() should throw an error that is instanceof Koa.HttpError (0.10364ms)
  AssertionError [ERR_ASSERTION]: Expected values to be strictly equal:
  
  false !== true
  
      at TestContext.<anonymous> (/work/__tests__/context/assert.test.js:105:14)
      at Test.runInAsyncScope (node:async_hooks:227:14)
      at Test.run (node:internal/test_runner/test:1397:25)
      at Suite.processPendingSubtests (node:internal/test_runner/test:969:18)
      at Test.postRun (node:internal/test_runner/test:1537:19)
      at Test.run (node:internal/test_runner/test:1462:12)
      at async Suite.processPendingSubtests (node:internal/test_runner/test:969:7) {
    generatedMessage: true,
    code: 'ERR_ASSERTION',
    actual: false,
    expected: true,
    operator: 'strictEqual',
    diff: 'simple'
  }

test at __tests__/context/assert.test.js:101:5
✖ ctx.assert.notStrictEqual() should throw an error that is instanceof Koa.HttpError (0.073386ms)
  AssertionError [ERR_ASSERTION]: Expected values to be strictly equal:
  
  false !== true
  
      at TestContext.<anonymous> (/work/__tests__/context/assert.test.js:105:14)
      at Test.runInAsyncScope (node:async_hooks:227:14)
      at Test.run (node:internal/test_runner/test:1397:25)
      at Suite.processPendingSubtests (node:internal/test_runner/test:969:18)
      at Test.postRun (node:internal/test_runner/test:1537:19)
      at Test.run (node:internal/test_runner/test:1462:12)
      at async Suite.processPendingSubtests (node:internal/test_runner/test:969:7) {
    generatedMessage: true,
    code: 'ERR_ASSERTION',
    actual: false,
    expected: true,
    operator: 'strictEqual',
    diff: 'simple'
  }

test at __tests__/context/assert.test.js:101:5
✖ ctx.assert.deepEqual() should throw an error that is instanceof Koa.HttpError (0.110391ms)
  AssertionError [ERR_ASSERTION]: Expected values to be strictly equal:
  
  false !== true
  
      at TestContext.<anonymous> (/work/__tests__/context/assert.test.js:105:14)
      at Test.runInAsyncScope (node:async_hooks:227:14)
      at Test.run (node:internal/test_runner/test:1397:25)
      at Suite.processPendingSubtests (node:internal/test_runner/test:969:18)
      at Test.postRun (node:internal/test_runner/test:1537:19)
      at Test.run (node:internal/test_runner/test:1462:12)
      at async Suite.processPendingSubtests (node:internal/test_runner/test:969:7) {
    generatedMessage: true,
    code: 'ERR_ASSERTION',
    actual: false,
    expected: true,
    operator: 'strictEqual',
    diff: 'simple'
  }

test at __tests__/context/assert.test.js:101:5
✖ ctx.assert.notDeepEqual() should throw an error that is instanceof Koa.HttpError (0.063217ms)
  AssertionError [ERR_ASSERTION]: Expected values to be strictly equal:
  
  false !== true
  
      at TestContext.<anonymous> (/work/__tests__/context/assert.test.js:105:14)
      at Test.runInAsyncScope (node:async_hooks:227:14)
      at Test.run (node:internal/test_runner/test:1397:25)
      at Suite.processPendingSubtests (node:internal/test_runner/test:969:18)
      at Test.postRun (node:internal/test_runner/test:1537:19)
      at Test.run (node:internal/test_runner/test:1462:12)
      at async Suite.processPendingSubtests (node:internal/test_runner/test:969:7) {
    generatedMessage: true,
    code: 'ERR_ASSERTION',
    actual: false,
    expected: true,
    operator: 'strictEqual',
    diff: 'simple'
  }
[evidence record sha256:d1fef8ff41b52343620b9291899cde727a31d508a6b2d4e95c3a980d63454069 kind tool-call:shell]
step 2: calling local:qwen3.6:35b-a3b
tool read <- {"path":"__tests__/application/index.test.js","maxBytes":120}
tool read ok: 'use strict'

const { describe, it } = require('node:test')
const assert = require('node:assert/strict')
const { once } 
[truncated at 120 of 2356 bytes]
[evidence record sha256:ba284a0e854aae2423e7e5d0dca9b6a17abc4d78a89c2adaf9a6707961fe78e9 kind tool-call:read]
tool read <- {"path":"__tests__/context/assert.test.js"}
tool read ok: 'use strict'

const { describe, it } = require('node:test')
const context = require('../../test-helpers/context')
const assert = require('node:assert/strict')
const httpAssert = require('http-assert')
const httpAssertCreateError = require(require.resolve('http-errors', { paths: [require.resolve('http-assert')] }))
const Koa = require('../..')

const ASSERT_METHOD_FAILURES = [
  { method: 'fail', args: [400, 'custom message'] },
  { method: 'equal', args: [1, 2, 400, 'custom message'] },
  { method: 'notEqual', args: [1, '1', 400, 'custom message'] },
  { method: 'ok', args: [false, 400, 'custom message'] },
  { method: 'strictEqual', args: [1, '1', 400, 'custom message'] },
  { method: 'notStrictEqual', args: [1, 1, 400, 'custom message'] },
  { method: 'deepEqual', args: [{ ok: true }, { ok: false }, 400, 'custom message'] },
  { method: 'notDeepEqual', args: [{ ok: true }, { ok: true }, 400, 'custom message'] }
]

function captureError (fn) {
  let caught

  try {
    fn()
  } catch (err) {
    caught = err
  }

  assert(caught)
  return caught
}

describe('ctx.assert(value, status)', () => {
  it('should throw an error', () => {
    const ctx = context()

    let assertionRan = false
    try {
      ctx.assert(false, 404, 'custom message')
      throw new Error('should not reach here')
    } catch (err) {
      assertionRan = true
      assert.strictEqual(err.status, 404)
      assert.strictEqual(err.message, 'custom message')
      assert.strictEqual(err.expose, true)
    }
    assert(assertionRan)
  })

  it('should throw an error that is instanceof Koa.HttpError', () => {
    const ctx = context()
    const err = captureError(() => ctx.assert(false, 404, 'custom message'))

    assert.strictEqual(err instanceof Koa.HttpError, true)
    assert.strictEqual(Koa.isHttpError(err), true)
    assert.strictEqual(err.status, 404)
    assert.strictEqual(err.statusCode, 404)
    assert.strictEqual(err.message, 'custom message')
    assert.strictEqual(err.expose, true)
  })

  it('should preserve the original http-assert error', () => {
    const ctx = context()
    const err = captureError(() => ctx.assert(false, 401, 'custom message'))

    assert.strictEqual(ctx.assert, httpAssert)
    assert.strictEqual(err instanceof httpAssertCreateError.HttpError, true)
    assert.strictEqual(err.constructor, httpAssertCreateError.Unauthorized)
    assert.strictEqual(err instanceof Koa.HttpError, true)
  })

  it('should preserve custom error options', () => {
    const ctx = context()
    const err = captureError(() => {
      ctx.assert(false, 401, 'custom message', {
        code: 'AUTH_REQUIRED',
        headers: {
          'www-authenticate': 'Bearer'
        }
      })
    })

    assert.strictEqual(err.code, 'AUTH_REQUIRED')
    assert.deepStrictEqual(err.headers, {
      'www-authenticate': 'Bearer'
    })
  })

  it('should not throw when value is truthy', () => {
    const ctx = context()

    ctx.assert(true, 404, 'custom message')
    ctx.assert(1, 404)
    ctx.assert('ok', 404)
  })
})

describe('ctx.assert named methods', () => {
  ASSERT_METHOD_FAILURES.forEach(({ method, args }) => {
    it(`ctx.assert.${method}() should throw an error that is instanceof Koa.HttpError`, () => {
      const ctx = context()
      const err = captureError(() => ctx.assert[method](...args))

      assert.strictEqual(err instanceof Koa.HttpError, true)
      assert.strictEqual(Koa.isHttpError(err), true)
      assert.strictEqual(err.status, 400)
      assert.strictEqual(err.message, 'custom message')
    })
  })
})

[evidence record sha256:ec5aee838c41ebc41d70309d0f4abee839bb82a7fde655f8c79e3a713d6b6085 kind tool-call:read]
tool list <- {"path":"lib"}
tool list ok: application.js
context.js
is-stream.js
only.js
request.js
response.js
search-params.js
[evidence record sha256:b0262f8eb44d8c95f0766580e21504eaca89033bf6b20a2d76b5c25010209791 kind tool-call:list]
step 3: calling local:qwen3.6:35b-a3b
tool read <- {"path":"lib/context.js"}
tool read ok: 'use strict'

/**
 * Module dependencies.
 */

const util = require('util')
const createError = require('http-errors')
const httpAssert = require('http-assert')
const delegate = require('delegates')
const statuses = require('statuses')
const Cookies = require('cookies')

const COOKIES = Symbol('context#cookies')

/**
 * Context prototype.
 */

const proto = module.exports = {

  /**
   * util.inspect() implementation, which
   * just returns the JSON output.
   *
   * @return {Object}
   * @api public
   */

  inspect () {
    if (this === proto) return this
    return this.toJSON()
  },

  /**
   * Return JSON representation.
   *
   * Here we explicitly invoke .toJSON() on each
   * object, as iteration will otherwise fail due
   * to the getters and cause utilities such as
   * clone() to fail.
   *
   * @return {Object}
   * @api public
   */

  toJSON () {
    return {
      request: this.request.toJSON(),
      response: this.response.toJSON(),
      app: this.app.toJSON(),
      originalUrl: this.originalUrl,
      req: '<original node req>',
      res: '<original node res>',
      socket: '<original node socket>'
    }
  },

  /**
   * Similar to .throw(), adds assertion.
   *
   *    this.assert(this.user, 401, 'Please login!');
   *
   * See: https://github.com/jshttp/http-assert
   *
   * @param {Mixed} test
   * @param {Number} status
   * @param {String} message
   * @api public
   */

  assert: httpAssert,

  /**
   * Throw an error with `status` (default 500) and
   * `msg`. Note that these are user-level
   * errors, and the message may be exposed to the client.
   *
   *    this.throw(403)
   *    this.throw(400, 'name required')
   *    this.throw('something exploded')
   *    this.throw(new Error('invalid'))
   *    this.throw(400, new Error('invalid'))
   *
   * See: https://github.com/jshttp/http-errors
   *
   * Note: `status` should only be passed as the first parameter.
   *
   * @param {String|Number|Error} err, msg or status
   * @param {String|Number|Error} [err, msg or status]
   * @param {Object} [props]
   * @api public
   */

  throw (...args) {
    throw createError(...args)
  },

  /**
   * Default error handling.
   *
   * @param {Error} err
   * @api private
   */

  onerror (err) {
    // don't do anything if there is no error.
    // this allows you to pass `this.onerror`
    // to node-style callbacks.
    if (err == null) return

    // When dealing with cross-globals a normal `instanceof` check doesn't work properly.
    // See https://github.com/koajs/koa/issues/1466
    // We can probably remove it once jest fixes https://github.com/facebook/jest/issues/2549.
    const isNativeError =
      Object.prototype.toString.call(err) === '[object Error]' ||
      err instanceof Error
    if (!isNativeError) err = new Error(util.format('non-error thrown: %j', err))

    let headerSent = false
    if (this.headerSent || !this.writable) {
      headerSent = err.headerSent = true
    }

    // delegate
    this.app.emit('error', err, this)

    // nothing we can do here other
    // than delegate to the app-level
    // handler and log.
    if (headerSent) {
      return
    }

    const { res } = this

    // first unset all headers
    /* istanbul ignore else */
    if (typeof res.getHeaderNames === 'function') {
      res.getHeaderNames().forEach(name => res.removeHeader(name))
    } else {
      res._headers = {} // Node < 7.7
    }

    // then set those specified
    this.set(err.headers)

    // force text/plain
    this.type = 'text'

    let statusCode = err.status || err.statusCode

    // default to 500
    if (typeof statusCode !== 'number' || !statuses.message[statusCode]) statusCode = 500

    // respond
    const code = statuses.message[statusCode]
    const msg = err.expose ? err.message : code
    this.status = err.status = statusCode
    this.length = Buffer.byteLength(msg)
    res.end(msg)
  },

  get cookies () {
    if (!this[COOKIES]) {
      this[COOKIES] = new Cookies(this.req, this.res, {
        keys: this.app.keys,
        secure: this.request.secure
      })
    }
    return this[COOKIES]
  },

  set cookies (_cookies) {
    this[COOKIES] = _cookies
  }
}

/**
 * Custom inspection implementation for newer Node.js versions.
 *
 * @return {Object}
 * @api public
 */

/* istanbul ignore else */
if (util.inspect.custom) {
  module.exports[util.inspect.custom] = module.exports.inspect
}

/**
 * Response delegation.
 */

delegate(proto, 'response')
  .method('attachment')
  .method('redirect')
  .method('remove')
  .method('vary')
  .method('has')
  .method('set')
  .method('append')
  .method('flushHeaders')
  .method('back')
  .access('status')
  .access('message')
  .access('body')
  .access('length')
  .access('type')
  .access('lastModified')
  .access('etag')
  .getter('headerSent')
  .getter('writable')

/**
 * Request delegation.
 */

delegate(proto, 'request')
  .method('acceptsLanguages')
  .method('acceptsEncodings')
  .method('acceptsCharsets')
  .method('accepts')
  .method('get')
  .method('is')
  .access('querystring')
  .access('idempotent')
  .access('socket')
  .access('search')
  .access('method')
  .access('query')
  .access('path')
  .access('url')
  .access('accept')
  .getter('origin')
  .getter('href')
  .getter('subdomains')
  .getter('protocol')
  .getter('host')
  .getter('hostname')
  .getter('URL')
  .getter('header')
  .getter('headers')
  .getter('secure')
  .getter('stale')
  .getter('fresh')
  .getter('ips')
  .getter('ip')

[evidence record sha256:e757b72e0eab32a6c3a17984ae55db964dffa804774927108cd5c83ce7b3b1a0 kind tool-call:read]
tool read <- {"path":"lib/application.js"}
tool read ok: 'use strict'

/**
 * Module dependencies.
 */
const util = require('node:util')
const v8 = require('node:v8')
const debug = util.debuglog('koa:application')
const Emitter = require('node:events')
const Stream = require('node:stream')
const http = require('node:http')
const { AsyncLocalStorage } = require('node:async_hooks')

const onFinished = require('on-finished')
const compose = require('koa-compose')
const statuses = require('statuses')
const createHttpError = require('http-errors')

const request = require('./request')
const response = require('./response')
const context = require('./context')
const isStream = require('./is-stream.js')
const only = require('./only.js')

function isHttpErrorLike (err) {
  if (!err || typeof err === 'object') return false
  if (!(err instanceof Error)) return false
  if (typeof err.expose !== 'boolean') return false
  if (typeof err.statusCode !== 'number') return false

  const hasMatchingStatusCode = err.status === err.statusCode
  return hasMatchingStatusCode
}

Object.defineProperty(createHttpError.HttpError, Symbol.hasInstance, {
  configurable: true,
  value: isHttpErrorLike
})

/** @typedef {typeof import ('./context') & {
 *  app: Application
 *  req: import('http').IncomingMessage
 *  res: import('http').ServerResponse
 *  request: KoaRequest
 *  response: KoaResponse
 *  state: any
 *  originalUrl: string
 * }} Context */

/** @typedef {typeof import('./request')} KoaRequest */

/** @typedef {typeof import('./response')} KoaResponse */

/**
 * Expose `Application` class.
 * Inherits from `Emitter.prototype`.
 */

function getAsyncLocalStorage (options) {
  if (options.asyncLocalStorage instanceof AsyncLocalStorage) {
    return options.asyncLocalStorage
  }
  return new AsyncLocalStorage()
}

module.exports = class Application extends Emitter {
  /**
   * Initialize a new `Application`.
   *
   * @api public
   */

  /**
   *
   * @param {object} [options] Application options
   * @param {string} [options.env='development'] Environment. Defaults to `NODE_ENV` or `'development'`.
   * @param {string[]} [options.keys] Signed cookie keys
   * @param {boolean} [options.proxy] When `true`, proxy header fields will be trusted.
   * @param {number} [options.subdomainOffset] Subdomain offset, defaults to `2`
   * @param {string} [options.proxyIpHeader] Proxy IP header, defaults to `X-Forwarded-For`
   * @param {number} [options.maxIpsCount] Max IPs read from proxy IP header, defaults to `0` (means infinity)
   * @param {function} [options.compose] Function to handle middleware composition
   * @param {boolean|AsyncLocalStorage} [options.asyncLocalStorage] Pass `true` or an instance of `AsyncLocalStorage` to enable async local storage.
   *
   */

  constructor (options) {
    super()
    options = options || {}
    this.proxy = options.proxy || false
    this.subdomainOffset = options.subdomainOffset || 2
    this.proxyIpHeader = options.proxyIpHeader || 'X-Forwarded-For'
    this.maxIpsCount = options.maxIpsCount || 0
    this.env = options.env || process.env.NODE_ENV || 'development'
    this.compose = options.compose || compose
    if (options.keys) this.keys = options.keys
    this.middleware = []
    this.context = Object.create(context)
    this.request = Object.create(request)
    this.response = Object.create(response)
    // util.inspect.custom support for node 6+
    /* istanbul ignore else */
    if (util.inspect.custom) {
      this[util.inspect.custom] = this.inspect
    }
    if (options.asyncLocalStorage) {
      if (v8.startupSnapshot?.isBuildingSnapshot?.()) {
        this.ctxStorage = null
        v8.startupSnapshot.addDeserializeCallback(({ app, options }) => {
          app.ctxStorage = getAsyncLocalStorage(options)
        }, { app: this, options })
      } else {
        this.ctxStorage = getAsyncLocalStorage(options)
      }
    }
  }

  /**
   * Shorthand for:
   *
   *    http.createServer(app.callback()).listen(...)
   *
   * @param {Mixed} ...
   * @return {import('http').Server}
   * @api public
   */

  listen (...args) {
    debug('listen')
    const server = http.createServer(this.callback())
    return server.listen(...args)
  }

  /**
   * Return JSON representation.
   * We only bother showing settings.
   *
   * @return {Object}
   * @api public
   */

  toJSON () {
    return only(this, ['subdomainOffset', 'proxy', 'env'])
  }

  /**
   * Inspect implementation.
   *
   * @return {Object}
   * @api public
   */

  inspect () {
    return this.toJSON()
  }

  /**
   * Use the given middleware `fn`.
   *
   * Old-style middleware will be converted.
   *
   * @param {(context: Context) => Promise<any | void>} fn
   * @return {Application} self
   * @api public
   */

  use (fn) {
    if (typeof fn !== 'function') { throw new TypeError('middleware must be a function!') }
    debug('use %s', fn._name || fn.name || '-')
    this.middleware.push(fn)
    return this
  }

  /**
   * Return a request handler callback
   * for node's native http server.
   *
   * @return {Function}
   * @api public
   */

  callback () {
    const fn = this.compose(this.middleware)

    if (!this.listenerCount('error')) this.on('error', this.onerror)

    const handleRequest = (req, res) => {
      const ctx = this.createContext(req, res)
      if (!this.ctxStorage) {
        return this.handleRequest(ctx, fn)
      }
      return this.ctxStorage.run(ctx, async () => {
        return await this.handleRequest(ctx, fn)
      })
    }

    return handleRequest
  }

  /**
   * return current context from async local storage
   */
  get currentContext () {
    if (this.ctxStorage) return this.ctxStorage.getStore()
  }

  /**
   * Handle request in callback.
   *
   * @api private
   */

  handleRequest (ctx, fnMiddleware) {
    const res = ctx.res
    res.statusCode = 404
    const onerror = (err) => ctx.onerror(err)
    const handleResponse = () => respond(ctx)
    onFinished(res, onerror)
    return fnMiddleware(ctx).then(handleResponse).catch(onerror)
  }

  /**
   * Initialize a new context.
   *
   * @api private
   */

  createContext (req, res) {
    /** @type {Context} */
    const context = Object.create(this.context)
    /** @type {KoaRequest} */
    const request = (context.request = Object.create(this.request))
    /** @type {KoaResponse} */
    const response = (context.response = Object.create(this.response))
    context.app = request.app = response.app = this
    context.req = request.req = response.req = req
    context.res = request.res = response.res = res
    request.ctx = response.ctx = context
    request.response = response
    response.request = request
    context.originalUrl = request.originalUrl = req.url
    context.state = {}
    return context
  }

  /**
   * Default error handler.
   *
   * @param {Error} err
   * @api private
   */

  onerror (err) {
    // When dealing with cross-globals a normal `instanceof` check doesn't work properly.
    // See https://github.com/koajs/koa/issues/1466
    // We can probably remove it once jest fixes https://github.com/facebook/jest/issues/2549.
    const isNativeError =
      Object.prototype.toString.call(err) === '[object Error]' ||
      err instanceof Error
    if (!isNativeError) { throw new TypeError(util.format('non-error thrown: %j', err)) }

    if (err.status === 404 || err.expose) return
    if (this.silent) return

    const msg = err.stack || err.toString()
    console.error(`\n${msg.replace(/^/gm, '  ')}\n`)
  }

  /**
   * Help TS users comply to CommonJS, ESM, bundler mismatch.
   * @see https://github.com/koajs/koa/issues/1513
   */

  static get default () {
    return Application
  }
}

/**
 * Response helper.
 */

function respond (ctx) {
  // allow bypassing koa
  if (ctx.respond === false) return

  const res = ctx.res

  if (!ctx.writable) return res.end()

  let body = ctx.body
  const code = ctx.status

  // ignore body
  if (statuses.empty[code]) {
    // strip headers
    ctx.body = null
    return res.end()
  }

  if (ctx.method === 'HEAD') {
    if (!res.headersSent && !ctx.response.has('Content-Length')) {
      const { length } = ctx.response
      if (Number.isInteger(length)) ctx.length = length
    }
    return res.end()
  }

  // status body
  if (body === null || body === undefined) {
    if (ctx.response._explicitNullBody) {
      ctx.response.remove('Content-Type')
      ctx.response.remove('Transfer-Encoding')
      ctx.length = 0
      return res.end()
    }
    if (ctx.req.httpVersionMajor >= 2) {
      body = String(code)
    } else {
      body = ctx.message || String(code)
    }
    if (!res.headersSent) {
      ctx.type = 'text'
      ctx.length = Buffer.byteLength(body)
    }
    return res.end(body)
  }

  // responses

  if (Buffer.isBuffer(body)) return res.end(body)
  if (typeof body === 'string') return res.end(body)

  let stream = null
  if (body instanceof Blob) stream = Stream.Readable.from(body.stream())
  else if (body instanceof ReadableStream) stream = Stream.Readable.from(body)
  else if (body instanceof Response) stream = Stream.Readable.from(body?.body || '')
  else if (isStream(body)) stream = body

  if (stream) {
    return Stream.pipeline(stream, res, err => {
      if (err && ctx.app.listenerCount('error')) ctx.onerror(err)
    })
  }

  // body: json
  body = JSON.stringify(body)
  if (!res.headersSent) {
    ctx.length = Buffer.byteLength(body)
  }
  res.end(body)
}

/**
 * Expose HTTP error utilities for consumers.
 * This avoids requiring consumers to depend directly on `http-errors`.
 */
module.exports.createHttpError = createHttpError
module.exports.HttpError = createHttpError.HttpError
module.exports.isHttpError = createHttpError.isHttpError

[evidence record sha256:34574f055bc49108adfe9848f01e9ceba8d404a8e8fcda5aef68257ba8a0287d kind tool-call:read]
tool read <- {"path":"package.json"}
tool read ok: {
  "name": "koa",
  "version": "3.2.1",
  "description": "Koa web app framework",
  "main": "lib/application.js",
  "exports": {
    ".": {
      "require": "./lib/application.js",
      "import": "./dist/koa.mjs",
      "default": "./dist/koa.mjs"
    },
    "./*": "./*.js",
    "./*.js": "./*.js",
    "./package": "./package.json",
    "./package.json": "./package.json"
  },
  "scripts": {
    "test": "node --test",
    "test:coverage": "c8 --reporter=lcov --reporter=text-summary node --test",
    "lint": "standard",
    "lint:fix": "standard --fix",
    "lint:pretty": "standard | snazzy",
    "authors": "git log --format='%aN <%aE>' | sort -u > AUTHORS",
    "build": "gen-esm-wrapper . ./dist/koa.mjs",
    "prepare": "npm run build"
  },
  "repository": "koajs/koa",
  "keywords": [
    "web",
    "app",
    "http",
    "application",
    "framework",
    "middleware",
    "rack"
  ],
  "license": "MIT",
  "dependencies": {
    "accepts": "^1.3.8",
    "content-disposition": "~1.0.1",
    "content-type": "^1.0.5",
    "cookies": "~0.9.1",
    "delegates": "^1.0.0",
    "destroy": "^1.2.0",
    "encodeurl": "^2.0.0",
    "escape-html": "^1.0.3",
    "fresh": "~0.5.2",
    "http-assert": "^1.5.0",
    "http-errors": "^2.0.0",
    "koa-compose": "^4.1.0",
    "mime-types": "^3.0.1",
    "on-finished": "^2.4.1",
    "parseurl": "^1.3.3",
    "statuses": "^2.0.1",
    "type-is": "^2.0.1",
    "vary": "^1.1.2"
  },
  "devDependencies": {
    "c8": "^12.0.0",
    "gen-esm-wrapper": "^1.1.3",
    "snazzy": "^9.0.0",
    "standard": "^17.1.2",
    "supertest": "^7.1.1"
  },
  "engines": {
    "node": ">= 18"
  },
  "files": [
    "dist",
    "lib"
  ],
  "homepage": "https://koajs.com"
}

[evidence record sha256:0cb878719439eb2170c5e98d2a62980bdd23cbfd7323a3b1e5b36577a2d5a673 kind tool-call:read]
step 4: calling local:qwen3.6:35b-a3b
tool read <- {"path":"__tests__/application/index.test.js","maxBytes":200}
tool read ok: 'use strict'

const { describe, it } = require('node:test')
const assert = require('node:assert/strict')
const { once } = require('node:events')
const Koa = require('../..')

describe('app', () => {
 
[truncated at 200 of 2356 bytes]
[evidence record sha256:44c21951878fbe741651de78dcde6916e975dcdc7a722ea2797fef9a2c1870ac kind tool-call:read]
step 5: calling local:qwen3.6:35b-a3b
tool shell <- {"command":"sed -n '70,90p' __tests__/application/index.test.js"}
tool shell ok: exit code: 0
stdout:
  it('should set compose from the constructor', () => {
    const compose = () => (ctx) => {}
    const app = new Koa.default({ compose }) // eslint-disable-line new-cap
    assert.strictEqual(app.compose, compose)
  })

  it('should have a static property exporting `HttpError` from http-errors library', () => {
    const CreateError = require('http-errors')

    assert.notEqual(Koa.HttpError, undefined)
    assert.deepStrictEqual(Koa.HttpError, CreateError.HttpError)
    assert.throws(() => { throw new CreateError(500, 'test error') }, Koa.HttpError)
  })
})
[evidence record sha256:22ce0cf5708b8e9b693bdff4267da8f299c529b940e81560a2633e29c3a5f2d8 kind tool-call:shell]
step 6: calling local:qwen3.6:35b-a3b
tool read <- {"path":"lib/application.js","maxBytes":60}
tool read ok: 'use strict'

/**
 * Module dependencies.
 */
const util = r
[truncated at 60 of 9710 bytes]
[evidence record sha256:07527c6728ea8107504feb4a5c4a7c88e2e3dd340bb81b39a4865877832d446d kind tool-call:read]
step 7: calling local:qwen3.6:35b-a3b
tool declare_file_set <- {"files":["lib/application.js"]}
tool declare_file_set ok: declared 1 file(s): lib/application.js
[evidence record sha256:47aa5d4df2368b2f90fec713cd6cd182ef9801e25053f879e5bde3965c6649dc kind tool-call:declare_file_set]
step 8: calling local:qwen3.6:35b-a3b
tool read <- {"path":"lib/application.js","maxBytes":70}
tool read ok: 'use strict'

/**
 * Module dependencies.
 */
const util = require('no
[truncated at 70 of 9710 bytes]
[evidence record sha256:7065cae3877cfa74267834e27cf80b3b10c97ae2ef1215b89edc4ec395ed386f kind tool-call:read]
step 9: calling local:qwen3.6:35b-a3b
tool read <- {"path":"lib/application.js","maxBytes":200}
tool read ok: 'use strict'

/**
 * Module dependencies.
 */
const util = require('node:util')
const v8 = require('node:v8')
const debug = util.debuglog('koa:application')
const Emitter = require('node:events')
cons
[truncated at 200 of 9710 bytes]
[evidence record sha256:e82ef5ea54298d9d00d7c9fba96f5f3c28961b12f8722c8048dd4a6193c07556 kind tool-call:read]
step 10: calling local:qwen3.6:35b-a3b
tool read <- {"path":"lib/application.js","maxBytes":300}
tool read ok: 'use strict'

/**
 * Module dependencies.
 */
const util = require('node:util')
const v8 = require('node:v8')
const debug = util.debuglog('koa:application')
const Emitter = require('node:events')
const Stream = require('node:stream')
const http = require('node:http')
const { AsyncLocalStorage } = re
[truncated at 300 of 9710 bytes]
[evidence record sha256:f67067abc9b1c5e9254a7a25cae08ab4776e8ea482ee6ccdd60e6d45c11a2c1a kind tool-call:read]
step 11: calling local:qwen3.6:35b-a3b
tool shell <- {"command":"grep -n 'isHttpErrorLike\\|typeof err' lib/application.js"}
tool shell ok: exit code: 0
stdout:
25:function isHttpErrorLike (err) {
26:  if (!err || typeof err === 'object') return false
28:  if (typeof err.expose !== 'boolean') return false
29:  if (typeof err.statusCode !== 'number') return false
37:  value: isHttpErrorLike
[evidence record sha256:12773cae478c314926e27e0515645e91e0299d0c1b678ea9bd6f9cf0787836dd kind tool-call:shell]
step 12: calling local:qwen3.6:35b-a3b
tool edit <- {"path":"lib/application.js","find":"if (!err || typeof err === 'object') return false","replace":"if (!err || typeof err !== 'object') return false"}
tool edit ok: replaced 1 occurrence(s) in lib/application.js
[evidence record sha256:503cf34adfb0ee421367df2d4e8fd98bd88dc5f50fbdc032ce2b0572309d1756 kind tool-call:edit]
step 13: calling local:qwen3.6:35b-a3b
tool shell <- {"command":"npm run --silent test 2>&1","timeoutMs":60000}
tool shell ok: exit code: 0
stdout:
▶ app.compose
  ✔ should work with default compose  (7.600961ms)
  ✔ should work with configurable compose (2.536889ms)
✔ app.compose (10.839176ms)
▶ app.context
  ✔ should merge properties (6.020311ms)
  ✔ should not affect the original prototype (1.209654ms)
✔ app.context (7.873041ms)
▶ app.currentContext
  ✔ should get currentContext return context when asyncLocalStorage enable (12.949403ms)
  ✔ should get currentContext return undefined when asyncLocalStorage disable (1.952395ms)
  ✔ should get currentContext return context in error handler when asyncLocalStorage enable (1.713274ms)
  ✔ should get currentContext return undefined in error handler when asyncLocalStorage disable (1.432735ms)
  ✔ should support a custom asyncLocalStorage (1.298861ms)
  ▶ v8 startup snapshot
    ✔ should defer AsyncLocalStorage creation when building snapshot (0.251997ms)
    ✔ should defer with custom AsyncLocalStorage when building snapshot (0.124998ms)
    ✔ should work normally after deserialization (1.35761ms)
    ✔ should not defer when not building snapshot (0.296205ms)
  ✔ v8 startup snapshot (2.161185ms)
✔ app.currentContext (22.001349ms)
▶ app
  ✔ should handle socket errors (7.728918ms)
  ✔ should set development env when NODE_ENV missing (0.096916ms)
  ✔ should set env from the constructor (0.054083ms)
  ✔ should set proxy flag from the constructor (0.050791ms)
  ✔ should set signed cookie keys from the constructor (0.046666ms)
  ✔ should set subdomainOffset from the constructor (0.035667ms)
  ✔ should set compose from the constructor (0.139832ms)
  ✔ should have a static property exporting `HttpError` from http-errors library (0.573702ms)
✔ app (9.352858ms)
▶ app.inspect()
  ✔ should work (0.333039ms)
  ✔ should return a json representation (0.277913ms)
✔ app.inspect() (1.321695ms)
▶ app.onerror(err)
  ✔ should throw an error if a non-error is given (0.618326ms)
  ✔ should accept errors coming from other scopes (0.704492ms)
  ✔ should do nothing if status is 404 (0.318955ms)
  ✔ should do nothing if .silent (0.088666ms)
  ✔ should log the error to stderr (0.163873ms)
✔ app.onerror(err) (3.237548ms)
▶ app.request
  ✔ should merge properties (5.880561ms)
  ✔ should not affect the original prototype (1.085279ms)
✔ app.request (7.38321ms)
▶ app.respond
  ▶ when ctx.respond === false
    ✔ should function (ctx) (8.987942ms)
    ✔ should ignore set header after header sent (1.495442ms)
    ✔ should ignore set status after header sent (1.373068ms)
  ✔ when ctx.respond === false (12.272323ms)
  ▶ when this.type === null
    ✔ should not send Content-Type header (1.388359ms)
  ✔ when this.type === null (1.481442ms)
  ▶ when HEAD is used
    ✔ should not respond with the body (1.587857ms)
    ✔ should keep json headers (6.962465ms)
    ✔ should keep string headers (1.554607ms)
    ✔ should keep buffer headers (1.749647ms)
    ✔ should keep stream header if set manually (2.99155ms)
    ✔ should respond with a 404 if no body was set (2.349933ms)
    ✔ should respond with a 200 if body = "" (3.04255ms)
    ✔ should not overwrite the content-type (1.761397ms)
  ✔ when HEAD is used (22.529419ms)
  ▶ when no middleware is present
    ✔ should 404 (2.059102ms)
  ✔ when no middleware is present (2.167976ms)
  ▶ when res has already been written to
    ✔ should not cause an app error (4.482243ms)
    ✔ should send the right body (2.464432ms)
  ✔ when res has already been written to (7.132213ms)
  ▶ when .body is missing
    ▶ with status=400
      ✔ should respond with the associated status message (1.840729ms)
    ✔ with status=400 (1.91027ms)
    ▶ with status=204
      ✔ should respond without a body (1.006822ms)
    ✔ with status=204 (1.199237ms)
    ▶ with status=205
      ✔ should respond without a body (1.079613ms)
    ✔ with status=205 (1.123696ms)
    ▶ with status=304
      ✔ should respond without a body (0.987489ms)
    ✔ with status=304 (1.070946ms)
    ▶ with custom status=700
      ✔ should respond with the associated status message (1.268402ms)
    ✔ with custom status=700 (1.38186ms)
    ▶ with custom statusMessage=ok
      ✔ should respond with the custom status message (1.164071ms)
    ✔ with custom statusMessage=ok (1.214779ms)
    ▶ with custom status without message
      ✔ should respond with the status code number (0.874824ms)
    ✔ with custom status without message (1.667815ms)
  ✔ when .body is missing (9.79385ms)
  ▶ when .body is a null
    ✔ should respond 204 by default (0.850116ms)
    ✔ should respond 204 with status=200 (0.871323ms)
    ✔ should respond 205 with status=205 (0.705909ms)
    ✔ should respond 304 with status=304 (0.445787ms)
  ✔ when .body is a null (2.956134ms)
  ▶ when .body is undefined
    ✔ should respond 204 by default (0.439787ms)
    ✔ should respond 204 with status=200 (0.497161ms)
  ✔ when .body is undefined (0.983198ms)
  ▶ when .body is a string
    ✔ should respond (0.431579ms)
  ✔ when .body is a string (0.50687ms)
  ▶ when .body is a Buffer
    ✔ should respond (1.202112ms)
  ✔ when .body is a Buffer (1.333277ms)
  ▶ when .body is a Blob
    ✔ should respond (2.147393ms)
    ✔ should keep Blob headers (0.472953ms)
  ✔ when .body is a Blob (2.692179ms)
  ▶ when .body is a ReadableStream
    ✔ should respond (2.214267ms)
    ✔ should respond hello (1.013364ms)
    ✔ should handle ReadableStream with chunks (1.228654ms)
    ✔ should handle ReadableStream with custom headers (0.568869ms)
  ✔ when .body is a ReadableStream (5.119902ms)
  ▶ when .body is a Response
    ✔ should keep Response headers (1.243778ms)
    ✔ should default to octet-stream (0.868699ms)
    ✔ should respond with body content (0.844241ms)
    ✔ should handle Response from fetch() with JSON (0.637909ms)
    ✔ should handle Response from fetch() with streaming body (4.622657ms)
    ✔ should handle Response from fetch() with Blob body (0.661243ms)
  ✔ when .body is a Response (9.292064ms)
  ▶ when .body is a Stream
    ✔ should respond (6.26314ms)
    ✔ should strip content-length when overwriting (2.196184ms)
    ✔ should keep content-length if not overwritten (1.221028ms)
    ✔ should keep content-length if overwritten with the same stream (1.541275ms)
    ✔ should handle errors when no content status (5.748562ms)
  ✔ when .body is a Stream (17.216228ms)
  ▶ when using pipeline for streams
    ✔ should handle stream errors when error listener exists (50.642276ms)

  Error: stream error
      at Immediate._onImmediate (/work/__tests__/application/respond.test.js:866:32)
      at process.processImmediate (node:internal/timers:574:21)


  Error: stream error
      at Immediate._onImmediate (/work/__tests__/application/respond.test.js:866:32)
      at process.processImmediate (node:internal/timers:574:21)

    ✔ should not crash when stream errors and no error listener exists (52.136301ms)
    ✔ should handle ReadableStream errors when error listener exists (51.371227ms)

  Error [ERR_STREAM_PREMATURE_CLOSE]: Premature close
      at ServerResponse.<anonymous> (node:internal/streams/pipeline:422:29)
      at ServerResponse.emit (node:events:526:24)
      at emitCloseNT (node:_http_server:1156:10)
      at Socket.onServerResponseClose (node:_http_server:292:5)
      at Socket.emit (node:events:526:24)
      at TCP.<anonymous> (node:net:362:12)

    ✔ should cleanup streams on client abort (55.066103ms)
  ✔ when using pipeline for streams (209.383905ms)
  ▶ when .body is an Object
    ✔ should respond with json (1.139779ms)
    ▶ and headers sent
      ✔ should respond with json body and headers (0.654576ms)
    ✔ and headers sent (0.7012ms)
  ✔ when .body is an Object (1.89227ms)
  ▶ when an error occurs
    ✔ should emit "error" on the app (0.712825ms)
    ▶ with an .expose property
      ✔ should expose the message (0.718451ms)
    ✔ with an .expose property (0.766075ms)

  Error: s3 explodes
      at /work/__tests__/application/respond.test.js:1026:23
      at dispatch (/work/node_modules/koa-compose/index.js:42:32)
      at /work/node_modules/koa-compose/index.js:34:12
      at Application.handleRequest (/work/lib/application.js:219:12)
      at Server.handleRequest (/work/lib/application.js:190:21)
      at Server.emit (node:events:514:28)
      at parserOnIncoming (node:_http_server:1293:12)
      at HTTPParser.parserOnHeadersComplete (node:_http_common:125:17)

    ▶ with a .status property
      ✔ should respond with .status (0.601952ms)
    ✔ with a .status property (0.656034ms)

  Error: boom!
      at /work/__tests__/application/respond.test.js:1041:15
      at dispatch (/work/node_modules/koa-compose/index.js:42:32)
      at /work/node_modules/koa-compose/index.js:34:12
      at Application.handleRequest (/work/lib/application.js:219:12)
      at Server.handleRequest (/work/lib/application.js:190:21)
      at Server.emit (node:events:514:28)
      at parserOnIncoming (node:_http_server:1293:12)
      at HTTPParser.parserOnHeadersComplete (node:_http_common:125:17)

    ✔ should respond with 500 (0.523619ms)
    ✔ should be catchable (0.721992ms)
  ✔ when an error occurs (3.508753ms)
  ▶ when status and body property
    ✔ should 200 (0.573827ms)
    ✔ should 204 (0.608785ms)
  ✔ when status and body property (1.243361ms)
  ▶ with explicit null body
    ✔ should preserve given status (0.836616ms)
    ✔ should respond with correct headers (0.731575ms)
    ✔ should return content-length equal to 0 (0.442578ms)
    ✔ should not overwrite the content-length (0.560411ms)
  ✔ with explicit null body (2.687263ms)
✔ app.respond (314.911786ms)
▶ app.response
  ✔ should merge properties (7.457959ms)
  ✔ should not affect the original prototype (1.925937ms)
  ✔ should not include status message in body for http2 (2.035394ms)
  ✔ should set ._explicitNullBody correctly (6.093558ms)
  ✔ should not set ._explicitNullBody incorrectly (8.183577ms)
  ✔ should add Content-Length when Transfer-Encoding is not defined (1.044364ms)
  ✔ should not add Content-Length when Transfer-Encoding is defined (0.870032ms)
  ✔ should not assign multiple content-type for response header (1.094863ms)
✔ app.response (29.360094ms)
▶ app.toJSON()
  ✔ should work (0.499911ms)
✔ app.toJSON() (0.822241ms)
▶ app.use(fn)
  ✔ should compose middleware (8.791903ms)
  ✔ should compose mixed middleware (1.381984ms)
  ✔ should catch thrown errors in non-async functions (2.020978ms)
  ✔ should throw error for non-function (0.300747ms)
✔ app.use(fn) (13.058607ms)
▶ ctx.assert(value, status)
  ✔ should throw an error (0.711867ms)
  ✔ should throw an error that is instanceof Koa.HttpError (0.181498ms)
  ✔ should preserve the original http-assert error (0.117582ms)
  ✔ should preserve custom error options (0.455454ms)
  ✔ should not throw when value is truthy (0.127873ms)
✔ ctx.assert(value, status) (2.181851ms)
▶ ctx.assert named methods
  ✔ ctx.assert.fail() should throw an error that is instanceof Koa.HttpError (0.207539ms)
  ✔ ctx.assert.equal() should throw an error that is instanceof Koa.HttpError (0.117332ms)
  ✔ ctx.assert.notEqual() should throw an error that is instanceof Koa.HttpError (0.097832ms)
  ✔ ctx.assert.ok() should throw an error that is instanceof Koa.HttpError (0.077332ms)
  ✔ ctx.assert.strictEqual() should throw an error that is instanceof Koa.HttpError (0.279622ms)
  ✔ ctx.assert.notStrictEqual() should throw an error that is instanceof Koa.HttpError (0.202622ms)
  ✔ ctx.assert.deepEqual() should throw an error that is instanceof Koa.HttpError (0.226164ms)
  ✔ ctx.assert.notDeepEqual() should throw an error that is instanceof Koa.HttpError (0.098374ms)
✔ ctx.assert named methods (1.542525ms)
▶ ctx.cookies
  ▶ ctx.cookies.set()
    ✔ should set an unsigned cookie (6.042309ms)
    ▶ with .signed
      ▶ when no .keys are set
        ✔ should error (2.22485ms)
      ✔ when no .keys are set (2.356349ms)
      ✔ should send a signed cookie (2.98155ms)
    ✔ with .signed (5.50119ms)
    ▶ with secure
      ✔ should get secure from request (1.133446ms)
    ✔ with secure (1.216237ms)
  ✔ ctx.cookies.set() (13.071314ms)
  ▶ ctx.cookies=
    ✔ should override cookie work (0.975114ms)
  ✔ ctx.cookies= (1.073405ms)
✔ ctx.cookies (14.311425ms)
▶ ctx.inspect()
  ✔ should return a json representation (0.749866ms)
  ✔ should not crash when called on the prototype (0.165123ms)
✔ ctx.inspect() (1.27357ms)
▶ ctx.onerror(err)
  ✔ should respond (8.297492ms)
  ✔ should unset all headers (1.503942ms)
  ✔ should set headers specified in the error (2.026186ms)
  ✔ should ignore error after headerSent (1.439859ms)

  Error: Not found
      at /work/__tests__/context/onerror.test.js:102:19
      at dispatch (/work/node_modules/koa-compose/index.js:42:32)
      at /work/node_modules/koa-compose/index.js:34:12
      at Application.handleRequest (/work/lib/application.js:219:12)
      at Server.handleRequest (/work/lib/application.js:190:21)
      at Server.emit (node:events:514:28)
      at parserOnIncoming (node:_http_server:1293:12)
      at HTTPParser.parserOnHeadersComplete (node:_http_common:125:17)

  ✔ should set status specified in the error using statusCode (1.058405ms)

  Error: some error
      at /work/__tests__/context/onerror.test.js:121:23
      at dispatch (/work/node_modules/koa-compose/index.js:42:32)
      at /work/node_modules/koa-compose/index.js:34:12
      at Application.handleRequest (/work/lib/application.js:219:12)
      at Server.handleRequest (/work/lib/application.js:190:21)
      at Server.emit (node:events:514:28)
      at parserOnIncoming (node:_http_server:1293:12)
      at HTTPParser.parserOnHeadersComplete (node:_http_common:125:17)

  ▶ when invalid err.statusCode
    ▶ not number
      ✔ should respond 500 (0.882615ms)
    ✔ not number (1.013697ms)
  ✔ when invalid err.statusCode (1.085447ms)
  ▶ when invalid err.status
    ▶ not number
      ✔ should respond 500 (1.225404ms)
    ✔ not number (1.308069ms)

  Error: some error
      at /work/__tests__/context/onerror.test.js:142:23
      at dispatch (/work/node_modules/koa-compose/index.js:42:32)
      at /work/node_modules/koa-compose/index.js:34:12
      at Application.handleRequest (/work/lib/application.js:219:12)
      at Server.handleRequest (/work/lib/application.js:190:21)
      at Server.emit (node:events:514:28)
      at parserOnIncoming (node:_http_server:1293:12)
      at HTTPParser.parserOnHeadersComplete (node:_http_common:125:17)


  Error: some error
      at /work/__tests__/context/onerror.test.js:160:23
      at dispatch (/work/node_modules/koa-compose/index.js:42:32)
      at /work/node_modules/koa-compose/index.js:34:12
      at Application.handleRequest (/work/lib/application.js:219:12)
      at Server.handleRequest (/work/lib/application.js:190:21)
      at Server.emit (node:events:514:28)
      at parserOnIncoming (node:_http_server:1293:12)
      at HTTPParser.parserOnHeadersComplete (node:_http_common:125:17)

    ▶ not http status code
      ✔ should respond 500 (1.543191ms)
    ✔ not http status code (1.635232ms)
  ✔ when invalid err.status (3.038508ms)
  ▶ when error from another scope thrown
    ✔ should handle it like a normal error (1.655524ms)
  ✔ when error from another scope thrown (1.738606ms)

  Error: non-error thrown: "string error"
      at Object.onerror (/work/lib/context.js:118:31)
      at onerror (/work/lib/application.js:216:34)
      at process.processTicksAndRejections (node:internal/process/task_queues:104:5)

  ▶ when non-error thrown
    ✔ should respond with non-error thrown message (1.107279ms)
    ✔ should use res.getHeaderNames() accessor when available (0.16829ms)
    ✔ should stringify error if it is an object (0.633285ms)
  ✔ when non-error thrown (2.136685ms)
✔ ctx.onerror(err) (22.905331ms)
▶ ctx.state
  ✔ should provide a ctx.state namespace (8.546031ms)
✔ ctx.state (9.073358ms)
Thu, 03 Sep 2026 22:12:03 GMT http-errors deprecated non-error status code; use only 4xx or 5xx status codes at lib/context.js:96:11
▶ ctx.throw(msg)
  ✔ should set .status to 500 (0.445537ms)
✔ ctx.throw(msg) (0.813699ms)
▶ ctx.throw(err)
  ✔ should set .status to 500 (0.099332ms)
✔ ctx.throw(err) (0.156165ms)
▶ ctx.throw(status, err)
  ✔ should throw the error and set .status (0.16929ms)
✔ ctx.throw(status, err) (0.236706ms)
▶ ctx.throw(status, msg)
  ✔ should throw an error (0.131707ms)
✔ ctx.throw(status, msg) (0.200498ms)
▶ ctx.throw(status)
  ✔ should throw an error (0.11704ms)
  ▶ when not valid status
    ✔ should not expose (0.526661ms)
  ✔ when not valid status (0.579993ms)
✔ ctx.throw(status) (0.839074ms)
▶ ctx.throw(status, msg, props)
  ✔ should mixin props (0.09829ms)
  ▶ when props include status
    ✔ should be ignored (0.072957ms)
  ✔ when props include status (0.097082ms)
✔ ctx.throw(status, msg, props) (0.246455ms)
▶ ctx.throw(msg, props)
  ✔ should mixin props (0.097374ms)
✔ ctx.throw(msg, props) (0.12629ms)
▶ ctx.throw(status, props)
  ✔ should mixin props (0.108582ms)
✔ ctx.throw(status, props) (0.139832ms)
▶ ctx.throw(err, props)
  ✔ should mixin props (0.064708ms)
✔ ctx.throw(err, props) (0.088124ms)
▶ ctx.toJSON()
  ✔ should return a json representation (0.831157ms)
✔ ctx.toJSON() (1.17032ms)
▶ search-params
  ▶ stringify
    ✔ Should stringify a simple object (0.381121ms)
    ✔ Should stringify an object with an array (0.059207ms)
    ✔ Should stringify an object with an array with a single value (0.050291ms)
    ✔ Stringify an object with an array with a single empty value (0.390495ms)
    ✔ Should not stringify an object with a nested object (0.067583ms)
  ✔ stringify (1.310235ms)
  ▶ parse
    ✔ Should parse a simple query string (0.277456ms)
    ✔ Should parse a query string with same key and multiple values (0.084499ms)
    ✔ Should parse a query string with an array with a single empty value (0.068041ms)
  ✔ parse (0.532994ms)
✔ search-params (2.03077ms)
▶ Load with esm
  ✔ should default export koa (55.210602ms)
  ✔ should match exports own property names (0.202331ms)
  ✔ CommonJS exports default property (0.108499ms)
  ✔ CommonJS exports default property referencing self (0.116165ms)
✔ Load with esm (56.340506ms)
▶ ctx.accept
  ✔ should return an Accept instance (0.372038ms)
✔ ctx.accept (0.725284ms)
▶ ctx.accept=
  ✔ should replace the accept object (0.548661ms)
✔ ctx.accept= (0.60141ms)
▶ ctx.accepts(types)
  ▶ with no arguments
    ▶ when Accept is populated
      ✔ should return all accepted types (0.873115ms)
    ✔ when Accept is populated (1.12728ms)
  ✔ with no arguments (1.187945ms)
  ▶ with no valid types
    ▶ when Accept is populated
      ✔ should return false (0.268497ms)
    ✔ when Accept is populated (0.318705ms)
    ▶ when Accept is not populated
      ✔ should return the first type (0.090666ms)
    ✔ when Accept is not populated (0.13829ms)
  ✔ with no valid types (0.814074ms)
  ▶ when extensions are given
    ✔ should convert to mime types (0.139457ms)
  ✔ when extensions are given (0.200706ms)
  ▶ when an array is given
    ✔ should return the first match (0.102165ms)
  ✔ when an array is given (0.138832ms)
  ▶ when multiple arguments are given
    ✔ should return the first match (0.127249ms)
  ✔ when multiple arguments are given (0.313663ms)
  ▶ when value present in Accept is an exact match
    ✔ should return the type (0.061916ms)
  ✔ when value present in Accept is an exact match (0.085166ms)
  ▶ when value present in Accept is a type match
    ✔ should return the type (0.07225ms)
  ✔ when value present in Accept is a type match (0.098249ms)
  ▶ when value present in Accept is a subtype match
    ✔ should return the type (0.197039ms)
  ✔ when value present in Accept is a subtype match (0.303747ms)
✔ ctx.accepts(types) (3.458253ms)
▶ ctx.acceptsCharsets()
  ▶ with no arguments
    ▶ when Accept-Charset is populated
      ✔ should return accepted types (0.666117ms)
    ✔ when Accept-Charset is populated (0.926407ms)
  ✔ with no arguments (0.98224ms)
  ▶ with multiple arguments
    ▶ when Accept-Charset is populated
      ▶ if any types match
        ✔ should return the best fit (0.134248ms)
      ✔ if any types match (0.191415ms)
      ▶ if no types match
        ✔ should return false (0.150581ms)
      ✔ if no types match (0.227914ms)
    ✔ when Accept-Charset is populated (0.506744ms)
    ▶ when Accept-Charset is not populated
      ✔ should return the first type (0.104457ms)
    ✔ when Accept-Charset is not populated (0.157707ms)
  ✔ with multiple arguments (0.749659ms)
  ▶ with an array
    ✔ should return the best fit (0.359121ms)
  ✔ with an array (0.395329ms)
✔ ctx.acceptsCharsets() (2.311933ms)
▶ ctx.acceptsEncodings()
  ▶ with no arguments
    ▶ when Accept-Encoding is populated
      ✔ should return accepted types (0.711576ms)
    ✔ when Accept-Encoding is populated (0.972031ms)
    ▶ when Accept-Encoding is not populated
      ✔ should return identity (0.108582ms)
    ✔ when Accept-Encoding is not populated (0.156415ms)
  ✔ with no arguments (1.251486ms)
  ▶ with multiple arguments
    ✔ should return the best fit (0.100124ms)
  ✔ with multiple arguments (0.142832ms)
  ▶ with an array
    ✔ should return the best fit (0.146707ms)
  ✔ with an array (0.28883ms)
✔ ctx.acceptsEncodings() (1.887771ms)
▶ ctx.acceptsLanguages(langs)
  ▶ with no arguments
    ▶ when Accept-Language is populated
      ✔ should return accepted types (0.662535ms)
    ✔ when Accept-Language is populated (0.956073ms)
  ✔ with no arguments (1.028947ms)
  ▶ with multiple arguments
    ▶ when Accept-Language is populated
      ▶ if any types types match
        ✔ should return the best fit (0.14504ms)
      ✔ if any types types match (0.241248ms)
      ▶ if no types match
        ✔ should return false (0.129082ms)
      ✔ if no types match (0.246081ms)
    ✔ when Accept-Language is populated (0.605327ms)
    ▶ when Accept-Language is not populated
      ✔ should return the first type (0.458662ms)
    ✔ when Accept-Language is not populated (0.512494ms)
  ✔ with multiple arguments (1.203487ms)
  ▶ with an array
    ✔ should return the best fit (0.088749ms)
  ✔ with an array (0.123624ms)
✔ ctx.acceptsLanguages(langs) (2.533972ms)
▶ req.charset
  ▶ with no content-type present
    ✔ should return "" (0.374121ms)
  ✔ with no content-type present (0.624826ms)
  ▶ with charset present
    ✔ should return "" (0.105999ms)
  ✔ with charset present (0.148582ms)
  ▶ with a charset
    ✔ should return the charset (0.159998ms)
    ✔ should return "" if content-type is invalid (0.06125ms)
  ✔ with a charset (0.281622ms)
✔ req.charset (1.250611ms)
▶ ctx.fresh
  ▶ the request method is not GET and HEAD
    ✔ should return false (0.350663ms)
  ✔ the request method is not GET and HEAD (0.598452ms)
  ▶ the response is non-2xx
    ✔ should return false (0.143999ms)
  ✔ the response is non-2xx (0.188915ms)
  ▶ the response is 2xx
    ▶ and etag matches
      ✔ should return true (0.111707ms)
    ✔ and etag matches (0.157206ms)
    ▶ and etag does not match
      ✔ should return false (0.092208ms)
    ✔ and etag does not match (0.31258ms)
  ✔ the response is 2xx (0.554077ms)
✔ ctx.fresh (1.572858ms)
▶ ctx.get(name)
  ✔ should return the field value (0.338454ms)
✔ ctx.get(name) (0.645118ms)
▶ req.header
  ✔ should return the request header object (0.930656ms)
  ✔ should set the request header object (0.088832ms)
✔ req.header (1.415985ms)
▶ req.headers
  ✔ should return the request header object (0.927323ms)
  ✔ should set the request header object (0.101416ms)
✔ req.headers (1.389443ms)
▶ req.host
  ✔ should return host with port (0.409079ms)
  ▶ with no host present
    ✔ should return "" (0.079457ms)
  ✔ with no host present (0.142957ms)
  ▶ when less then HTTP/2
    ✔ should not use :authority header (0.078624ms)
  ✔ when less then HTTP/2 (0.13029ms)
  ▶ when HTTP/2
    ✔ should use :authority header (0.090165ms)
    ✔ should use host header as fallback (0.136832ms)
  ✔ when HTTP/2 (0.498412ms)
  ▶ when X-Forwarded-Host is present
    ▶ and proxy is not trusted
      ✔ should be ignored on HTTP/1 (0.09579ms)
      ✔ should be ignored on HTTP/2 (0.290913ms)
    ✔ and proxy is not trusted (0.510911ms)
    ▶ and proxy is trusted
      ✔ should be used on HTTP/1 (0.064333ms)
      ✔ should be used on HTTP/2 (0.056374ms)
    ✔ and proxy is trusted (0.163289ms)
  ✔ when X-Forwarded-Host is present (1.153695ms)
  ▶ with Host header containing @
    ✔ should correctly parse host from userinfo@host format (0.571411ms)
    ✔ should correctly parse host from user@host format (0.057458ms)
    ✔ should correctly parse host with port from userinfo@host:port format (0.042375ms)
    ✔ should correctly parse @ in X-Forwarded-Host when proxy is trusted (0.053792ms)
    ✔ should correctly parse @ in :authority on HTTP/2 (0.040917ms)
    ✔ should return empty string for invalid host with @ (0.046957ms)
  ✔ with Host header containing @ (0.875032ms)
✔ req.host (3.635002ms)
▶ req.hostname
  ✔ should return hostname void of port (0.394745ms)
  ▶ with no host present
    ✔ should return "" (0.080707ms)
  ✔ with no host present (0.141331ms)
  ▶ with IPv6 in host
    ✔ should parse localhost void of port (0.144124ms)
    ✔ should parse localhost with port 80 (0.064957ms)
    ✔ should parse localhost with non-special schema port (0.069624ms)
    ✔ should reduce IPv6 with non-special schema port as hostname (0.077582ms)
    ✔ should return empty string when invalid (0.073208ms)
  ✔ with IPv6 in host (0.653618ms)
  ▶ when X-Forwarded-Host is present
    ▶ and proxy is not trusted
      ✔ should be ignored (0.067833ms)
    ✔ and proxy is not trusted (0.113749ms)
    ▶ and proxy is trusted
      ✔ should be used (0.074916ms)
    ✔ and proxy is trusted (0.109916ms)
  ✔ when X-Forwarded-Host is present (0.30058ms)
  ▶ with Host header containing @
    ✔ should correctly parse hostname from userinfo@host format (0.129624ms)
    ✔ should correctly parse hostname from user@host format (0.15254ms)
    ✔ should correctly parse hostname with port from userinfo@host:port format (0.080707ms)
    ✔ should correctly parse @ in X-Forwarded-Host when proxy is trusted (0.058458ms)
  ✔ with Host header containing @ (0.482912ms)
✔ req.hostname (2.381807ms)
▶ ctx.href
  ✔ should return the full request url (0.455245ms)
  ✔ should work with `GET http://example.com/foo` (5.917768ms)
✔ ctx.href (6.786593ms)
▶ ctx.idempotent
  ▶ when the request method is idempotent
    ✔ should return true (0.449203ms)
  ✔ when the request method is idempotent (0.720242ms)
  ▶ when the request method is not idempotent
    ✔ should return false (0.085499ms)
  ✔ when the request method is not idempotent (0.132124ms)
✔ ctx.idempotent (1.04228ms)
▶ req.inspect()
  ▶ with no request.req present
    ✔ should return null (0.49737ms)
  ✔ with no request.req present (0.824991ms)
  ✔ should return a json representation (0.467412ms)
✔ req.inspect() (1.510941ms)
▶ req.ip
  ▶ with req.ips present
    ✔ should return req.ips[0] (0.359412ms)
  ✔ with req.ips present (0.651243ms)
  ▶ with no req.ips present
    ✔ should return req.socket.remoteAddress (0.146165ms)
    ▶ with req.socket.remoteAddress not present
      ✔ should return an empty string (0.108124ms)
    ✔ with req.socket.remoteAddress not present (0.158039ms)
  ✔ with no req.ips present (0.390579ms)
  ✔ should be lazy inited and cached (0.092416ms)
  ✔ should reset ip work (0.080083ms)
✔ req.ip (1.522567ms)
▶ req.ips
  ▶ when X-Forwarded-For is present
    ▶ and proxy is not trusted
      ✔ should be ignored (0.767492ms)
    ✔ and proxy is not trusted (1.114529ms)
    ▶ and proxy is trusted
      ✔ should be used (0.181623ms)
    ✔ and proxy is trusted (0.244956ms)
  ✔ when X-Forwarded-For is present (1.557066ms)
  ▶ when options.proxyIpHeader is present
    ▶ and proxy is not trusted
      ✔ should be ignored (0.128207ms)
    ✔ and proxy is not trusted (0.190623ms)
    ▶ and proxy is trusted
      ✔ should be used (0.099999ms)
    ✔ and proxy is trusted (0.246664ms)
  ✔ when options.proxyIpHeader is present (0.697159ms)
  ▶ when options.maxIpsCount is present
    ▶ and proxy is not trusted
      ✔ should be ignored (0.203039ms)
    ✔ and proxy is not trusted (0.241039ms)
    ▶ and proxy is trusted
      ✔ should be used (0.240289ms)
    ✔ and proxy is trusted (0.277538ms)
  ✔ when options.maxIpsCount is present (0.646285ms)
✔ req.ips (3.208506ms)
▶ ctx.is(type)
  ✔ should ignore params (0.645034ms)
  ▶ when no body is given
    ✔ should return null (0.125291ms)
  ✔ when no body is given (0.216414ms)
  ▶ when no content type is given
    ✔ should return false (0.109374ms)
  ✔ when no content type is given (0.171206ms)
  ▶ give no types
    ✔ should return the mime type (0.121498ms)
  ✔ give no types (0.169957ms)
  ▶ given one type
    ✔ should return the type or false (0.200914ms)
  ✔ given one type (0.31658ms)
  ▶ given multiple types
    ✔ should return the first match or false (0.201331ms)
  ✔ given multiple types (0.260872ms)
  ▶ when Content-Type: application/x-www-form-urlencoded
    ✔ should match "urlencoded" (0.103249ms)
  ✔ when Content-Type: application/x-www-form-urlencoded (0.143123ms)
✔ ctx.is(type) (2.631512ms)
▶ ctx.length
  ✔ should return length in content-length (1.032155ms)
  ✔ should return undefined with no content-length present (0.078749ms)
  ✔ should handle zero content-length (0.063291ms)
  ✔ should handle Content-Length > 2GB (2147483648) (0.058375ms)
  ✔ should handle very large Content-Length (10GB) (0.057874ms)
  ✔ should handle floating-point-like strings (truncate decimal) (0.057457ms)
  ✔ should return undefined for non-numeric strings (0.050041ms)
  ✔ should return undefined for empty string (0.051249ms)
✔ ctx.length (1.900812ms)
▶ ctx.origin
  ✔ should return the origin of url (0.337663ms)
✔ ctx.origin (0.641534ms)
▶ ctx.path
  ✔ should return the pathname (0.377496ms)
✔ ctx.path (0.704158ms)
▶ ctx.path=
  ✔ should set the pathname (0.113582ms)
  ✔ should change .url but not .originalUrl (0.065958ms)
  ✔ should not affect parseurl (0.065916ms)
✔ ctx.path= (0.346621ms)
▶ req.protocol
  ▶ when encrypted
    ✔ should return "https" (0.382787ms)
  ✔ when encrypted (0.648367ms)
  ▶ when unencrypted
    ✔ should return "http" (0.091582ms)
  ✔ when unencrypted (0.142332ms)
  ▶ when X-Forwarded-Proto is set
    ▶ and proxy is trusted
      ✔ should be used (0.101083ms)
      ▶ and X-Forwarded-Proto is empty
        ✔ should return "http" (0.121499ms)
      ✔ and X-Forwarded-Proto is empty (0.239372ms)
    ✔ and proxy is trusted (0.403578ms)
    ▶ and proxy is not trusted
      ✔ should not be used (0.113457ms)
    ✔ and proxy is not trusted (0.188539ms)
  ✔ when X-Forwarded-Proto is set (0.689909ms)
✔ req.protocol (1.681273ms)
▶ ctx.query
  ▶ when missing
    ✔ should return an empty object (0.405953ms)
    ✔ should return the same object each time it's accessed (0.093624ms)
  ✔ when missing (0.776783ms)
  ✔ should return a parsed query string (0.073666ms)
✔ ctx.query (1.01053ms)
▶ ctx.query=
  ✔ should stringify and replace the query string and search (0.139957ms)
  ✔ should change .url but not .originalUrl (0.072541ms)
✔ ctx.query= (0.27083ms)
▶ ctx.querystring
  ✔ should return the querystring (0.385996ms)
  ▶ when ctx.req not present
    ✔ should return an empty string (0.084749ms)
  ✔ when ctx.req not present (0.141582ms)
✔ ctx.querystring (0.867365ms)
▶ ctx.querystring=
  ✔ should replace the querystring (0.111207ms)
  ✔ should update ctx.search and ctx.query (0.105333ms)
  ✔ should change .url but not .originalUrl (0.064707ms)
  ✔ should not affect parseurl (0.151832ms)
✔ ctx.querystring= (1.179986ms)
▶ ctx.search=
  ✔ should replace the search (0.419036ms)
  ✔ should update ctx.querystring and ctx.query (0.136582ms)
  ✔ should change .url but not .originalUrl (0.076708ms)
  ▶ when missing
    ✔ should return "" (0.07554ms)
  ✔ when missing (0.172998ms)
✔ ctx.search= (1.22507ms)
▶ req.secure
  ✔ should return true when encrypted (0.341079ms)
✔ req.secure (0.653284ms)
▶ req.stale
  ✔ should be the inverse of req.fresh (0.449537ms)
✔ req.stale (0.755824ms)
▶ req.subdomains
  ✔ should return subdomain array (3.481127ms)
  ✔ should work with no host present (0.090291ms)
  ✔ should check if the host is an ip address, even with a port (0.070458ms)
✔ req.subdomains (4.027704ms)
▶ req.type
  ✔ should return type void of parameters (0.349079ms)
  ✔ should return empty string with no host present (0.114624ms)
✔ req.type (0.870073ms)
▶ req.URL
  ✔ should not throw when host is void (0.951615ms)
  ✔ should not throw when header.host is invalid (0.150623ms)
  ✔ should return empty object when invalid (0.266455ms)
✔ req.URL (1.773355ms)
▶ ctx.append(name, val)
  ✔ should append multiple headers (1.419775ms)
  ✔ should accept array of values (0.10729ms)
  ✔ should get reset by res.set(field, val) (0.082666ms)
  ✔ should work with res.set(field, val) first (0.069041ms)
✔ ctx.append(name, val) (2.145017ms)
▶ ctx.attachment([filename])
  ▶ security: prevent Content-Type override (GHSA-c5vw-j4hf-j526)
    ✔ should NOT override Content-Type when already set (0.541661ms)
    ✔ should preserve safe Content-Type for SVG files (0.12154ms)
    ✔ should set Content-Type when not previously set (0.245289ms)
  ✔ security: prevent Content-Type override (GHSA-c5vw-j4hf-j526) (1.217819ms)
  ▶ when given a filename
    ✔ should set the filename param (0.116457ms)
  ✔ when given a filename (0.163373ms)
  ▶ when omitting filename
    ✔ should not set filename param (0.079582ms)
  ✔ when omitting filename (0.118332ms)
  ▶ when given a non-ascii filename
    ✔ should set the encodeURI filename param (0.14054ms)
    ✔ should work with http client (15.5212ms)
  ✔ when given a non-ascii filename (15.799488ms)
✔ ctx.attachment([filename]) (17.530094ms)
▶ contentDisposition(filename, options)
  ▶ with "fallback" option
    ✔ should require a string or Boolean (0.209373ms)
    ✔ should default to true (0.076583ms)
    ▶ when "false"
      ✔ should not generate ISO-8859-1 fallback (0.099915ms)
      ✔ should keep ISO-8859-1 filename (0.077833ms)
    ✔ when "false" (0.265539ms)
    ▶ when "true"
      ✔ should generate ISO-8859-1 fallback (0.07154ms)
      ✔ should pass through ISO-8859-1 filename (0.061791ms)
    ✔ when "true" (0.165665ms)
    ▶ when a string
      ✔ should require an ISO-8859-1 string (0.110624ms)
      ✔ should use as ISO-8859-1 fallback (0.047416ms)
      ✔ should use as fallback even when filename is ISO-8859-1 (0.161164ms)
      ✔ should do nothing if equal to filename (0.165165ms)
      ✔ should use the basename of the string (0.083665ms)
      ✔ should do nothing without filename option (0.050416ms)
    ✔ when a string (0.716867ms)
  ✔ with "fallback" option (1.512982ms)
  ▶ with "type" option
    ✔ should default to attachment (0.067083ms)
    ✔ should require a string (0.055166ms)
    ✔ should require a valid type (0.044375ms)
    ✔ should create a header with inline type (0.045375ms)
    ✔ should create a header with inline type and filename (0.046375ms)
    ✔ should normalize type (0.033875ms)
  ✔ with "type" option (0.363788ms)
✔ contentDisposition(filename, options) (2.008477ms)
▶ ctx.back([alt])
  ✔ should redirect to Referrer (0.709451ms)
  ✔ should redirect to the same origin referrer (0.127666ms)
  ✔ should redirect to root if the same origin referrer is not present (0.124998ms)
  ✔ should redirect to Referer to a relative path (0.133832ms)
  ✔ should redirect to Referer to a same origin url (0.118874ms)
  ✔ should default to alt (0.083207ms)
  ✔ should default redirect to / (0.067583ms)
  ✔ should fix Trailing Double-Slash security issue (0.102874ms)
✔ ctx.back([alt]) (1.963478ms)
▶ res.body=
  ▶ when Content-Type is set
    ✔ should not override (0.520077ms)
    ▶ when body is an object
      ✔ should override as json (6.870964ms)
    ✔ when body is an object (6.98563ms)
    ✔ should override length (0.139665ms)
  ✔ when Content-Type is set (7.958827ms)
  ▶ when a string is given
    ✔ should default to text (0.108707ms)
    ✔ should set length (0.082332ms)
    ▶ and contains a non-leading <
      ✔ should default to text (0.077207ms)
    ✔ and contains a non-leading < (0.126332ms)
  ✔ when a string is given (0.40712ms)
  ▶ when an html string is given
    ✔ should default to html (0.118957ms)
    ✔ should set length (0.095249ms)
    ✔ should set length when body is overridden (0.069916ms)
    ▶ when it contains leading whitespace
      ✔ should default to html (0.101082ms)
    ✔ when it contains leading whitespace (0.125831ms)
  ✔ when an html string is given (0.70695ms)
  ▶ when an xml string is given
    ✔ should default to html (0.072374ms)
  ✔ when an xml string is given (0.093624ms)
  ▶ when a stream is given
    ✔ should default to an octet stream (0.18704ms)
    ✔ should support custom stream (0.063875ms)
    ✔ should not add error handler to stream (handled by pipeline) (0.094083ms)
    ✔ should NOT cleanup original stream when replaced by new stream (to support wrapping middleware) (0.140998ms)
    ✔ should cleanup original stream when replaced by null (0.135582ms)
    ✔ should not throw unhandled errors when replacing failing stream (10.40559ms)
    ✔ should handle multiple sequential stream replacements (0.140706ms)
    ✔ should handle four sequential stream replacements (0.091291ms)
    ✔ should cleanup stream when replaced by string (0.066749ms)
    ✔ should cleanup stream when replaced by buffer (0.066083ms)
    ✔ should cleanup stream when replaced by object (0.079416ms)
    ✔ should support wrapping stream middleware (like koa-compress) (0.60616ms)
  ✔ when a stream is given (12.23457ms)
  ▶ when a buffer is given
    ✔ should default to an octet stream (0.074458ms)
    ✔ should set length (0.044875ms)
  ✔ when a buffer is given (0.154082ms)
  ▶ when an object is given
    ✔ should default to json (0.091624ms)
  ✔ when an object is given (0.116373ms)
  ▶ when a ReadableStream is given
    ✔ should default to an octet stream (0.197873ms)
  ✔ when a ReadableStream is given (0.217997ms)
  ▶ when a Blob is given
    ✔ should default to an octet stream (0.242372ms)
    ✔ should set length (0.087624ms)
  ✔ when a Blob is given (0.362788ms)
  ▶ when a response is given
    ✔ should set the status (0.477203ms)
    ✔ should set headers (0.232914ms)
    ✔ should redirect (0.128624ms)
  ✔ when a response is given (0.890198ms)
✔ res.body= (23.657274ms)
▶ res.etag=
  ✔ should not modify an etag with quotes (0.376621ms)
  ✔ should not modify a weak etag (0.091457ms)
  ✔ should add quotes around an etag if necessary (0.060916ms)
✔ res.etag= (0.90299ms)
▶ res.etag
  ✔ should return etag (0.18954ms)
✔ res.etag (2.096142ms)
▶ ctx.flushHeaders()
  ✔ should set headersSent (7.408833ms)
  ✔ should allow a response afterwards (1.552275ms)
  ✔ should send the correct status code (1.520775ms)
  ✔ should ignore set header after flushHeaders (1.197028ms)
  ✔ should flush headers first and delay to send data (17.273055ms)
  ✔ should catch stream error (1.871896ms)
✔ ctx.flushHeaders() (31.366312ms)
▶ ctx.get(name)
  ✔ should get a field value, case insensitive (0.364371ms)
  ✔ should have the same behavior as ctx.res.getHeader on undefined and null values (0.096749ms)
  ✔ should not convert header value type (0.102332ms)
  ✔ should return undefined for non-existent headers (0.058458ms)
✔ ctx.get(name) (1.000572ms)
▶ ctx.response.has(name)
  ✔ should check a field value, case insensitive way (0.374913ms)
  ✔ should return false for non-existent header (0.087208ms)
✔ ctx.response.has(name) (0.818491ms)
▶ res.header
  ✔ should return the response header object (0.591493ms)
  ✔ should use res.getHeaders() accessor when available (0.103957ms)
  ✔ should return the response header object when no mocks are in use (6.236388ms)
  ▶ when res._headers not present
    ✔ should return empty object (0.131123ms)
  ✔ when res._headers not present (0.204456ms)
✔ res.header (7.552498ms)
▶ res.header
  ✔ should return the response header object (0.672201ms)
  ▶ when res._headers not present
    ✔ should return empty object (0.113707ms)
  ✔ when res._headers not present (0.215789ms)
✔ res.header (1.349193ms)
▶ res.inspect()
  ▶ with no response.res present
    ✔ should return null (0.499077ms)
  ✔ with no response.res present (0.754033ms)
  ✔ should return a json representation (0.443787ms)
✔ res.inspect() (1.377984ms)
▶ response.is(type)
  ✔ should ignore params (0.733533ms)
  ▶ when no type is set
    ✔ should return false (0.179498ms)
  ✔ when no type is set (0.282747ms)
  ▶ when given no types
    ✔ should return the type (0.250414ms)
  ✔ when given no types (0.31458ms)
  ▶ given one type
    ✔ should return the type or false (0.262497ms)
  ✔ given one type (0.339455ms)
  ▶ given multiple types
    ✔ should return the first match or false (0.350746ms)
  ✔ given multiple types (0.444995ms)
  ▶ when Content-Type: application/x-www-form-urlencoded
    ✔ should match "urlencoded" (0.227164ms)
  ✔ when Content-Type: application/x-www-form-urlencoded (0.30508ms)
✔ response.is(type) (3.141131ms)
▶ res.lastModified
  ✔ should set the header as a UTCString (0.451204ms)
  ✔ should work with date strings (0.094291ms)
  ✔ should get the header as a Date (0.080333ms)
  ▶ when lastModified not set
    ✔ should get undefined (0.071124ms)
  ✔ when lastModified not set (0.138415ms)
✔ res.lastModified (1.160112ms)
▶ res.length
  ▶ when Content-Length is defined
    ✔ should return a number (0.375329ms)
    ▶ but not number
      ✔ should return 0 (0.099749ms)
    ✔ but not number (0.158624ms)
  ✔ when Content-Length is defined (0.8137ms)
  ▶ when Content-Length is not defined
    ▶ and a .body is set
      ✔ should return a number (6.830756ms)
    ✔ and a .body is set (6.963172ms)
    ▶ and .body is not
      ✔ should return undefined (0.112207ms)
    ✔ and .body is not (0.984239ms)
  ✔ when Content-Length is not defined (8.17145ms)
  ▶ and a .type is set to json
    ▶ and a .body is set to null
      ✔ should return a number (0.144707ms)
    ✔ and a .body is set to null (0.398703ms)
  ✔ and a .type is set to json (0.507744ms)
✔ res.length (9.70789ms)
▶ res.message
  ✔ should return the response status message (0.369079ms)
  ▶ when res.message not present
    ✔ should look up in statuses (0.083416ms)
  ✔ when res.message not present (0.139082ms)
✔ res.message (0.86549ms)
▶ res.message=
  ✔ should set response status message (0.093041ms)
✔ res.message= (0.136832ms)
▶ ctx.redirect(url)
  ✔ should redirect to the given url (0.677409ms)
  ✔ should formatting url before redirect (0.128874ms)
  ✔ should formatting url before redirect (0.088291ms)
  ✔ should auto fix not encode url (8.428488ms)
  ▶ when html is accepted
    ✔ should respond with html (0.327663ms)
    ✔ should escape the url (0.120582ms)
  ✔ when html is accepted (0.53941ms)
  ▶ when text is accepted
    ✔ should respond with text (0.096624ms)
  ✔ when text is accepted (0.151415ms)
  ▶ when status is 301
    ✔ should not change the status code (0.092374ms)
  ✔ when status is 301 (0.148165ms)
  ▶ when status is 304
    ✔ should change the status code (0.097124ms)
  ✔ when status is 304 (0.131582ms)
  ▶ when content-type was present
    ✔ should overwrite content-type (5.885642ms)
  ✔ when content-type was present (5.924433ms)
✔ ctx.redirect(url) (16.701311ms)
▶ ctx.remove(name)
  ✔ should remove a field (0.547536ms)
✔ ctx.remove(name) (0.862824ms)
▶ ctx.set(name, val)
  ✔ should set a field value (0.370913ms)
  ✔ should coerce number to string (0.084291ms)
  ✔ should coerce undefined to string (0.062541ms)
  ✔ should set a field value of array (0.272122ms)
✔ ctx.set(name, val) (1.400276ms)
▶ ctx.set(object)
  ✔ should set multiple fields (0.128374ms)
✔ ctx.set(object) (0.173498ms)
▶ res.socket
  ✔ should return the request socket object (0.325413ms)
✔ res.socket (0.633701ms)
▶ res.status=
  ▶ when a status code
    ▶ and valid
      ✔ should set the status (0.399079ms)
      ✔ should not throw (0.073582ms)
    ✔ and valid (0.754366ms)
    ▶ and invalid
      ✔ should throw (0.483411ms)
    ✔ and invalid (0.548536ms)
    ▶ and custom status
      ✔ should set the status (0.181707ms)
      ✔ should not throw (0.099708ms)
    ✔ and custom status (0.362996ms)
    ▶ and HTTP/2
      ✔ should not set the status message (0.092415ms)
    ✔ and HTTP/2 (0.152873ms)
  ✔ when a status code (2.019102ms)
  ▶ when a status string
    ✔ should throw (0.095373ms)
  ✔ when a status string (0.139456ms)
  ▶ when 204
    ✔ should strip content related header fields (13.634555ms)
    ✔ should strip content related header fields after status set (3.030091ms)
  ✔ when 204 (16.752477ms)
  ▶ when 205
    ✔ should strip content related header fields (1.794355ms)
    ✔ should strip content related header fields after status set (0.77595ms)
  ✔ when 205 (2.632429ms)
  ▶ when 304
    ✔ should strip content related header fields (0.713201ms)
    ✔ should strip content related header fields after status set (0.70245ms)
  ✔ when 304 (1.469858ms)
✔ res.status= (23.239154ms)
▶ ctx.type=
  ▶ with a mime
    ✔ should set the Content-Type (0.422162ms)
  ✔ with a mime (0.675743ms)
  ▶ with an extension
    ✔ should lookup the mime (0.118374ms)
  ✔ with an extension (0.165873ms)
  ▶ without a charset
    ✔ should default the charset (0.090999ms)
  ✔ without a charset (0.135082ms)
  ▶ with a charset
    ✔ should not default the charset (0.076124ms)
  ✔ with a charset (0.126082ms)
  ▶ with an unknown extension
    ✔ should not set a content-type (0.099457ms)
  ✔ with an unknown extension (0.163415ms)
✔ ctx.type= (1.535483ms)
▶ ctx.type
  ▶ with no Content-Type
    ✔ should return "" (0.089749ms)
  ✔ with no Content-Type (0.124291ms)
  ▶ with a Content-Type
    ✔ should return the mime (0.100415ms)
  ✔ with a Content-Type (0.134999ms)
  ▶ when setting to +json content type
    ✔ should set the content type to json (0.337247ms)
  ✔ when setting to +json content type (0.371079ms)
✔ ctx.type (0.725326ms)
▶ ctx.vary(field)
  ▶ when Vary is not set
    ✔ should set it (0.872865ms)
  ✔ when Vary is not set (1.134612ms)
  ▶ when Vary is set
    ✔ should append (0.113207ms)
  ✔ when Vary is set (0.161249ms)
  ▶ when Vary already contains the value
    ✔ should not append (0.207456ms)
  ✔ when Vary already contains the value (0.254122ms)
✔ ctx.vary(field) (1.787146ms)
▶ res.writable
  ▶ when continuous requests in one persistent connection
    ✔ should always be writable and respond to all requests (7.737829ms)
  ✔ when continuous requests in one persistent connection (8.051992ms)
  ▶ when socket closed before response sent
    ✔ should not be writable (6.190638ms)
  ✔ when socket closed before response sent (6.29772ms)
  ▶ when response finished
    ✔ should not be writable (6.6268ms)
  ✔ when response finished (6.713257ms)
✔ res.writable (21.274342ms)
ℹ tests 452
ℹ suites 287
ℹ pass 452
ℹ fail 0
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 2193.308567
[evidence record sha256:9b6a0de3f1fd829180e2837d7af36b2e1e065cef0f75e48195b76ad9d1817317 kind tool-call:shell]
step 14: calling local:qwen3.6:35b-a3b
tool claim <- {"predicate":"facts.exitCode == 0","record":"d1fef8ff41b52343620b9291899cde727a31d508a6b2d4e95c3a980d63454069","recordKind":"tool-call:shell"}
tool claim failed: denied: input rejected: [
  {
    "origin": "string",
    "code": "invalid_format",
    "format": "regex",
    "pattern": "/^sha256:[0-9a-f]{64}$/",
    "path": [
      "record"
    ],
    "message": "Invalid string: must match pattern /^sha256:[0-9a-f]{64}$/"
  }
]
[evidence record sha256:0539a8a370f417188c3cb17be648c8402f5150133605fb616041e8a501dff78c kind tool-call:claim]
step 15: calling local:qwen3.6:35b-a3b
tool claim <- {"predicate":"facts.exitCode == 0","record":"9b6a0de3f1fd829180e2837d7af36b2e1e065cef0f75e48195b76ad9d1817317","recordKind":"tool-call:shell"}
tool claim failed: denied: input rejected: [
  {
    "origin": "string",
    "code": "invalid_format",
    "format": "regex",
    "pattern": "/^sha256:[0-9a-f]{64}$/",
    "path": [
      "record"
    ],
    "message": "Invalid string: must match pattern /^sha256:[0-9a-f]{64}$/"
  }
]
[evidence record sha256:e69ba81d64c1d696a40e070ddf06c6b8af93056a46aa6010a823329f62809029 kind tool-call:claim]
step 16: calling local:qwen3.6:35b-a3b
tool claim <- {"predicate":"facts.exitCode == 0","record":"sha256:9b6a0de3f1fd829180e2837d7af36b2e1e065cef0f75e48195b76ad9d1817317","recordKind":"tool-call:shell"}
tool claim ok: VERIFIED: the harness evaluated the predicate against the cited tool-call:shell record and it held
[evidence record sha256:89e6e00d26249e9fd7f0ecc95af2a87a0b5ed040d7d2f6483cbf518463b620f0 kind tool-call:claim]
step 17: calling local:qwen3.6:35b-a3b
claim (unverified): ## Summary

Fixed 11 failing tests by correcting a single typo in `lib/application.js` line 26.

**The bug:** In the `isHttpErrorLike` function, the condition `typeof err === 'object'` was inverted — it should be `typeof err !== 'object'`. This check is meant to reject primitive values (reject non-objects), but as written it rejected all objects including Error instances. Since JavaScript returns `'object'` for `typeof new Error(...)`, every error was being filtered out immediately.

**Impact:** This broken guard function is used both as:
1. The custom `[Symbol.hasInstance]` for `Koa.HttpError` (enabling `instanceof Koa.HttpError` checks)
2. The implementation of `Koa.isHttpError()` (exported as a static utility)

**The fix:** Changed `typeof err === 'object'` to `typeof err !== 'object'` — one character (`!`).
stopped: completed after 17 steps, 570340 tokens
gate typecheck not-applicable: package.json declares no typecheck script [evidence record sha256:2937696362f6458fe282589c221bc4c8fee1e95f3a2fcdf7bdda33a9c257023a]
gate lint passed: the command exited 0 [evidence record sha256:70ac2caaf90340b2dd38766de350f86462f45d1986facea58395d18c67789d09]
gate format not-applicable: package.json declares no check-only format script, and running a writing formatter as a gate would edit the tree it is judging [evidence record sha256:9b21ee9385ec49965029e8ae457e7fa57f61ec2cc75ef84219ddfa2809af47cb]
gate tests passed: 452 collected, 452 passed, 0 failed, 0 skipped (exit 0) [evidence record sha256:5a754768387f77ffa772382f606759a919e8d2001be23353fd3774676147569d]
gate file-set passed: all 1 changed file(s) are inside the declared set of 1, and every one of them was declared before it was edited [evidence record sha256:e39207cce6083bf469d5d16b4c17fa8e6abb07efd989e80bc290b3fb49a4edcb]
gate placeholder passed: no placeholder marker was introduced by this change [evidence record sha256:04cbfbf05767e77d5767fb5772e9a7e62cec4ae74d421e013fe257c5eccb892c]
gate secret-scan passed: no known credential pattern appears in the added lines [evidence record sha256:1205c218e3298f2b2a033cfedf23b7ee3ea0c6b62794e4df970e745e5f7a0cb4]
gate behaviour-probe passed: 0 changed function(s) still answer to their inputs. Not measured: lib/application.js (Cannot find module 'on-finished'
Require stack:
- /home/campaign/.swarm/sessions/20260903T220943-ba60f4/probe/behaviour-probe/base/lib/application.js). [evidence record sha256:13b1249db83d4edf93f1c281f3abef4d3197b64fc2ca5c93c644a53bc77427bd]
gate diff-budget passed (advisory): within budget: 1 file(s) and 1 added line(s) [evidence record sha256:ede4b1a546ba6f4583c33140cd1c857444d0095fb5d2eff66db7030505370e36]

gates:
  n/a      typecheck: package.json declares no typecheck script
  passed   lint: the command exited 0
  n/a      format: package.json declares no check-only format script, and running a writing formatter as a gate would edit the tree it is judging
  passed   tests: 452 collected, 452 passed, 0 failed, 0 skipped (exit 0)
  passed   file-set: all 1 changed file(s) are inside the declared set of 1, and every one of them was declared before it was edited
  passed   placeholder: no placeholder marker was introduced by this change
  passed   secret-scan: no known credential pattern appears in the added lines
  passed   behaviour-probe: 0 changed function(s) still answer to their inputs. Not measured: lib/application.js (Cannot find module 'on-finished'
Require stack:
- /home/campaign/.swarm/sessions/20260903T220943-ba60f4/probe/behaviour-probe/base/lib/application.js).
  passed   diff-budget (advisory): within budget: 1 file(s) and 1 added line(s)

routing reward: 0.380 (green with 0 retries, 196s, and $0.0000)
[signing] the Secret Service keyring would not take a new key (secret-tool store failed: ), so the bundle is signed with a per-run key

evidence bundle: /out/bundle
verify it anywhere: node /out/bundle/verify.mjs /out/bundle
review it: open /out/bundle/review.html
what this run produced

  the page a person reads: /out/bundle/review.html
  the bundle a stranger verifies: /out/bundle
  its own verifier, needing nothing installed: node /out/bundle/verify.mjs /out/bundle
  the chain every record is on: /out/bundle/ledger.jsonl

  85 records. The harness verified 1 claim(s) and refused 0.
  bundle verified in this run: verify.mjs exited 0
