{"record":{"id":"92787981a0a0536a","repo":"instructure/canvas-lms","slug":"no-table-prefix-specified-for-category-inspect","errorCode":null,"errorMessage":"No table prefix specified for: #{category.inspect}","messagePattern":"No table prefix specified for: #(.+?)","errorType":"validation","errorClass":"InvalidConfig","httpStatus":null,"severity":"error","filePath":"lib/canvas/dynamo_db/database_builder.rb","lineNumber":68,"sourceCode":"          opts[:endpoint] = config[:endpoint] if config[:endpoint]\n          fingerprint = \"#{category}:#{environment}\"\n          begin\n            @clients[key] = CanvasDynamoDB::Database.new(\n              fingerprint,\n              prefix: config[:table_prefix],\n              client_opts: opts,\n              logger: Rails.logger\n            )\n          rescue => e\n            Rails.logger.error \"Failed to create DynamoDB client for #{key}: #{e}\"\n            nil # don't save this nil into @clients[key], so we can retry later\n          end\n        end\n      end\n\n      def self.validate_config(config)\n        unless config[:table_prefix].present?\n          raise InvalidConfig, \"No table prefix specified for: #{category.inspect}\"\n        end\n        unless config[:region].present?\n          raise InvalidConfig, \"No region specified for: #{category.inspect}\"\n        end\n      end\n\n      def self.default_environment\n        Rails.env\n      end\n\n      def self.configs(environment = default_environment)\n        ConfigFile.load(\"dynamodb\", environment) || {}\n      end\n\n      def self.categories\n        configs.keys\n      end\n    end","sourceCodeStart":50,"sourceCodeEnd":86,"githubUrl":"https://github.com/instructure/canvas-lms/blob/1c9f0bb8013ed69c4f2efe11fd483025469b7e6c/lib/canvas/dynamo_db/database_builder.rb#L50-L86","documentation":"Canvas::DynamoDB::DatabaseBuilder.validate_config raises InvalidConfig 'No table prefix specified for: <category>' when the loaded config hash lacks a :table_prefix key (or it is blank). Table prefix is required to namespace the DynamoDB tables for that category. Note: the message interpolates `category`, which is not a parameter of validate_config — a latent NameError/bug alongside the intended message.","triggerScenarios":"Calling from_config for a category whose yaml config (config/<env>.yml or dynamo_db config) exists but omits table_prefix, then validate_config runs while building the client.","commonSituations":"Hand-rolled dynamo_db config entries missing table_prefix; copy-pasting a config block and deleting the prefix line; environments partially migrated to new config schemas.","solutions":["Add table_prefix to the category's config in the dynamo_db yaml for the environment.","Validate the config file shape after editing (all categories have table_prefix and region).","If the prefix genuinely shouldn't be needed, use a different storage backend; DynamoDB builder requires it.","Fix validate_config to interpolate the category argument (pass category in) so the error names the offending entry."],"exampleFix":"// before\ndynamo_db:\n  live_events:\n    region: us-east-1\n// after\ndynamo_db:\n  live_events:\n    region: us-east-1\n    table_prefix: live_events","handlingStrategy":"validation","validationCode":"# ruby\ncfg = configs(environment)[category]\ncfg[:table_prefix].present? && cfg[:region].present? or raise \"invalid dynamo config for #{category}\"","typeGuard":null,"tryCatchPattern":"begin\n  DatabaseBuilder.from_config(category)\nrescue Canvas::DynamoDB::DatabaseBuilder::InvalidConfig => e\n  abort(e.message)\nend","preventionTips":["Include table_prefix and region in every dynamo_db category entry.","Validate dynamo_db yaml at deploy/boot time.","Template the config so new categories can't omit required keys."],"tags":["dynamodb","config-validation","missing-key"],"backgroundTag":"missing-required-config-field","analyzedSha":"1c9f0bb8013ed69c4f2efe11fd483025469b7e6c","analyzedAt":"2026-09-15T20:33:18.891Z","contentChangedAt":"2026-09-15T20:33:18.891Z","schemaVersion":2},"datasetVersion":"2026-09-23T02:17:17.105Z"}