{"record":{"id":"817e712ae97e2b7c","repo":"discordjs/discord.js","slug":"defaultvaluegenerator-is-not-a-function","errorCode":null,"errorMessage":"${defaultValueGenerator} is not a function","messagePattern":"(.+?) is not a function","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"packages/collection/src/collection.ts","lineNumber":55,"sourceCode":" *\n * @typeParam Key - The key type this collection holds\n * @typeParam Value - The value type this collection holds\n */\n// eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging\nexport class Collection<Key, Value> extends Map<Key, Value> {\n\t/**\n\t * Obtains the value of the given key if it exists, otherwise sets and returns the value provided by the default value generator.\n\t *\n\t * @param key - The key to get if it exists, or set otherwise\n\t * @param defaultValueGenerator - A function that generates the default value\n\t * @example\n\t * ```ts\n\t * collection.ensure(guildId, () => defaultGuildConfig);\n\t * ```\n\t */\n\tpublic ensure(key: Key, defaultValueGenerator: (key: Key, collection: this) => Value): Value {\n\t\tif (this.has(key)) return this.get(key)!;\n\t\tif (typeof defaultValueGenerator !== 'function') throw new TypeError(`${defaultValueGenerator} is not a function`);\n\t\tconst defaultValue = defaultValueGenerator(key, this);\n\t\tthis.set(key, defaultValue);\n\t\treturn defaultValue;\n\t}\n\n\t/**\n\t * Checks if all of the elements exist in the collection.\n\t *\n\t * @param keys - The keys of the elements to check for\n\t * @returns `true` if all of the elements exist, `false` if at least one does not exist.\n\t */\n\tpublic hasAll(...keys: Key[]) {\n\t\treturn keys.every((key) => super.has(key));\n\t}\n\n\t/**\n\t * Checks if any of the elements exist in the collection.\n\t *","sourceCodeStart":37,"sourceCodeEnd":73,"githubUrl":"https://github.com/discordjs/discord.js/blob/a81ed8a306d37fdc746e26a634b6a42164ba2c8c/packages/collection/src/collection.ts#L37-L73","documentation":"Collection.ensure(key, defaultValueGenerator) only calls the generator if the key is absent. To keep the contract that the second argument is a factory function, it throws a TypeError when the argument is not callable, stringifying the offending value into the message.","triggerScenarios":"Calling collection.ensure(key, value) passing a non-function as the second argument — e.g. ensure('cfg', defaultConfig) instead of ensure('cfg', () => defaultConfig).","commonSituations":"Misreading the API as an upsert-with-value method; refactoring from get-or-set code that used plain values; copying ensure() usage from Map patterns where a default value (not factory) is expected.","solutions":["Wrap the default in a function: collection.ensure(key, () => defaultValue).","If you just want a stored value, use has/get/set instead of ensure.","Check the JSDoc example in collection.ts: `collection.ensure(guildId, () => defaultGuildConfig)`."],"exampleFix":"// before\ncollection.ensure(guildId, defaultGuildConfig);\n// after\ncollection.ensure(guildId, () => defaultGuildConfig);","handlingStrategy":"type-guard","validationCode":"if (typeof defaultValueGenerator !== 'function') {\n  throw new TypeError('ensure() requires a factory function');\n}","typeGuard":"function isFactory<V, K>(f: unknown): f is (key: K, collection: unknown) => V {\n  return typeof f === 'function';\n}","tryCatchPattern":"try {\n  collection.ensure(key, def as any);\n} catch (err) {\n  if (err instanceof TypeError && err.message.includes('is not a function')) {\n    collection.set(key, def);\n  } else throw err;\n}","preventionTips":["Always pass an arrow function: ensure(key, () => value).","Remember ensure takes a factory, not a value.","Add a lint rule or review note for Collection.ensure usage."],"tags":["collection","typeerror","api-misuse"],"backgroundTag":"callback-not-a-function","analyzedSha":"a81ed8a306d37fdc746e26a634b6a42164ba2c8c","analyzedAt":"2026-08-30T04:07:22.193Z","schemaVersion":2},"datasetVersion":"2026-08-30T08:17:16.595Z"}