{"record":{"id":"f4f90ed1cb5aa418","repo":"avajs/ava","slug":"expected-an-implementation","errorCode":null,"errorMessage":"Expected an implementation.","messagePattern":"Expected an implementation\\.","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"lib/test.js","lineNumber":105,"sourceCode":"\t\tthis.timeout.clear = () => {\n\t\t\ttest.clearTimeout();\n\t\t};\n\n\t\tthis.teardown = callback => {\n\t\t\ttest.addTeardown(callback);\n\t\t};\n\n\t\tthis.try = async (...attemptArgs) => {\n\t\t\tif (test.isHook) {\n\t\t\t\tconst error = new Error('`t.try()` can only be used in tests');\n\t\t\t\ttest.saveFirstError(error);\n\t\t\t\tthrow error;\n\t\t\t}\n\n\t\t\tconst {args, implementation, title} = parseTestArgs(attemptArgs);\n\n\t\t\tif (typeof implementation !== 'function') {\n\t\t\t\tthrow new TypeError('Expected an implementation.');\n\t\t\t}\n\n\t\t\tlet attemptTitle;\n\t\t\tif (!title.isSet || title.isEmpty) {\n\t\t\t\tattemptTitle = `${test.title} ─ attempt ${test.attemptCount + 1}`;\n\t\t\t} else if (title.isValid) {\n\t\t\t\tattemptTitle = `${test.title} ─ ${title.value}`;\n\t\t\t} else {\n\t\t\t\tthrow new TypeError('`t.try()` titles must be strings');\n\t\t\t}\n\n\t\t\tif (!test.registerUniqueTitle(attemptTitle)) {\n\t\t\t\tthrow new Error(`Duplicate test title: ${attemptTitle}`);\n\t\t\t}\n\n\t\t\tlet committed = false;\n\t\t\tlet discarded = false;\n","sourceCodeStart":87,"sourceCodeEnd":123,"githubUrl":"https://github.com/avajs/ava/blob/bbfd946322fdeca2b547a691d947fb4e18c0c67f/lib/test.js#L87-L123","documentation":"AVA's t.try() requires an implementation function as its argument (optionally with a title and args). When t.try() is called without a function (e.g. undefined, null, or only a non-function value), the constructor throws this TypeError because there is nothing to execute for the attempt.","triggerScenarios":"t.try() called with no arguments; t.try('title') with a title but no implementation; t.try(cb) where cb is undefined due to a bad import or hoisting issue; passing args-only without a function (e.g. t.try('title', arg1) missing the function).","commonSituations":"Refactoring renamed the callback so the variable is undefined; copying the t.try(title, impl, ...args) signature but forgetting impl; passing a non-function like a promise or an async result instead of the test function.","solutions":["Pass an actual function to t.try(): t.try(tt => { ... }) or t.try('title', tt => { ... }).","Verify the implementation identifier is defined and imported correctly (check for undefined variables/imports).","If passing arguments, use the signature t.try(title, implementation, ...args) with implementation as the second argument."],"exampleFix":"// before\nconst attempt = t.try('checks value', someValue);\n\n// after\nconst attempt = t.try('checks value', (tt, value) => {\n  tt.is(value, 42);\n}, someValue);","handlingStrategy":"validation","validationCode":"if (typeof impl !== 'function') throw new TypeError('t.try() requires an implementation function');\nconst attempt = t.try('title', impl, ...args);","typeGuard":"const isFunction = (v) => typeof v === 'function';","tryCatchPattern":"try {\n  attempt = t.try(...attemptArgs);\n} catch (err) {\n  if (err instanceof TypeError && err.message === 'Expected an implementation.') {\n    throw new Error('Bug in test: t.try() called without a function');\n  }\n  throw err;\n}","preventionTips":["Always pass the implementation as the last non-args argument to t.try()","Enable TypeScript or linter rules that catch non-function arguments","Check imports after refactors so the callback variable is never undefined","Remember the signature: t.try(title?, implementation, ...args)"],"tags":["ava","t-try","typeerror","missing-argument"],"backgroundTag":"expected-function-argument","analyzedSha":"bbfd946322fdeca2b547a691d947fb4e18c0c67f","analyzedAt":"2026-09-02T01:24:43.834Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T06:17:21.866Z"}