{"record":{"id":"7cc789d83f2b6729","repo":"denoland/deno","slug":"cannot-serve-http-requests-either-a-handler-or","errorCode":null,"errorMessage":"Cannot serve HTTP requests: either a `handler` or `options` must be specified","messagePattern":"Cannot serve HTTP requests: either a `handler` or `options` must be specified","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"ext/http/00_serve.ts","lineNumber":1173,"sourceCode":"\n// Flag to track if DENO_SERVE_ADDRESS override has been consumed\nlet serveAddressOverrideConsumed = false;\n\nfunction serve(arg1, arg2) {\n  let options: RawServeOptions | undefined;\n  let handler: RawHandler | undefined;\n\n  if (typeof arg1 === \"function\") {\n    handler = arg1;\n  } else if (typeof arg2 === \"function\") {\n    handler = arg2;\n    options = arg1;\n  } else {\n    options = arg1;\n  }\n  if (handler === undefined) {\n    if (options === undefined) {\n      throw new TypeError(\n        \"Cannot serve HTTP requests: either a `handler` or `options` must be specified\",\n      );\n    }\n    handler = options.handler;\n  }\n  if (typeof handler !== \"function\") {\n    throw new TypeError(\n      `Cannot serve HTTP requests: handler must be a function, received ${typeof handler}`,\n    );\n  }\n  if (options === undefined) {\n    options = { __proto__: null };\n  }\n\n  if (serveAddressOverrideConsumed) {\n    return serveInner(options, handler);\n  }\n","sourceCodeStart":1155,"sourceCodeEnd":1191,"githubUrl":"https://github.com/denoland/deno/blob/abd22074e47c6a5cd14e9e4e84743f084aa5a575/ext/http/00_serve.ts#L1155-L1191","documentation":"Deno.serve's argument parser accepts `serve(handler)`, `serve(options, handler)`, or `serve(optionsWithHandler)`; if none of the arguments is a function, `options` must exist and carry a `handler`. This TypeError fires when serve is called with no usable arguments at all — typically `Deno.serve()` or `Deno.serve(undefined)`. It is a startup-time configuration error, thrown synchronously before any listener is created.","triggerScenarios":"Calling `Deno.serve()` with zero arguments while wiring code up, passing an undefined variable as the only argument (`Deno.serve(missingHandler)` where the import failed silently), or passing a non-function first argument and a non-function second argument so options stays undefined.","commonSituations":"Scaffolding/boilerplate run before the handler is written, circular imports yielding undefined handlers, dynamic construction of the serve arguments from config that produced nothing.","solutions":["Pass a handler function: `Deno.serve(handler)` or `Deno.serve({ port: 8000, handler })`","If building options dynamically, fall back to a concrete options object: `Deno.serve(opts ?? { port: 8000, handler })`","Check for undefined before calling when handlers come from dynamic imports"],"exampleFix":"// before\nDeno.serve(); // no handler, no options\n\n// after\nDeno.serve({ port: 8000, handler: (req) => new Response('ok') });","handlingStrategy":"validation","validationCode":"// Verify arguments before calling serve:\nconst handler: Deno.ServeHandler | undefined = resolveHandler();\nif (typeof handler !== 'function') {\n  throw new Error('Deno.serve: no handler resolved — check dynamic imports');\n}\nDeno.serve({ port: 8000 }, handler);","typeGuard":"const isServeHandler = (v: unknown): v is Deno.ServeHandler =>\n  typeof v === 'function';","tryCatchPattern":null,"preventionTips":["Always pass either a function or an options object containing handler","Fail fast on undefined handlers from dynamic imports instead of forwarding them","Keep serve() calls in one place so the contract is easy to review"],"tags":["http","deno-serve","api-misuse","startup","validation"],"backgroundTag":"missing-request-handler","analyzedSha":"abd22074e47c6a5cd14e9e4e84743f084aa5a575","analyzedAt":"2026-08-20T13:07:44.778Z","contentChangedAt":"2026-08-20T13:07:44.778Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}