An opinionated framework for creating REST-like APIs in Ruby.
This report summarizes scanner evidence for ruby-grape/grape, a Ruby project with 10,011 GitHub stars. SynthScan examined 61,256 lines of code across 405 source files, recording 157 pattern matches distributed across 8 syntactic categories. The legacy adjusted pattern signal is 3.0 (Low pattern signal); it is not an authorship estimate.
Use the findings to ask whether maintainers can explain intent, verify dependencies, simplify unnecessary scaffolding, and focus review effort. Risk Payload v1 adds ownership, supply-chain, over-engineering, and review-effort vectors when available. These are prompts for human verification, not probabilities, security findings, or measured maintenance costs.
Use each vector to guide manual verification of the underlying findings.
Payload schema: 1.0.0 · Engine: 2.0.0 · Scoring: heuristic-density-v1 · Scan date: 2026-10-31.
Can maintainers explain intent, assumptions, and trade-offs? 156 finding(s).
Are imports declared and package/API names verified? 0 finding(s).
Are wrappers, guards, and repeated structures necessary? 32 finding(s).
Which changes need focused human review? 157 finding(s).
This chart tracks the legacy adjusted pattern score across scan runs. Changes can reflect source changes, scan coverage, or detector/scoring versions; they do not measure AI adoption or prove that a team refactored code. Compare runs only when their scoring versions are compatible. The dashed line tracks the raw pattern-hit count.
Groups findings by configured severity weight. Severity is not a confidence estimate, security rating, or proof that a package is missing. Verify imports against the project's manifests and inspect each finding in its local design context.
This horizontal bar chart shows where configured pattern scores accumulate across directories. Treat the bars as locations to inspect, not as evidence of authorship or code quality. Use the file-level findings to decide whether a directory needs a focused ownership, dependency, complexity, or review check.
The scanner identified 157 distinct pattern matches across 8 syntactic categories. Each entry below represents a discrete location in the source code where the engine recorded a detector match to inspect in context. Expand any category row to inspect the individual file paths, line numbers, code snippets, and the lexical context (CODE, COMMENT, or STRING) in which each match was detected.
Reading the findings table: The Severity column indicates the configured finding weight (CRITICAL / HIGH / MEDIUM / LOW). The Context column identifies whether the match occurred inside executable code, an inline comment, or a string literal — legacy comment-context matches receive a ×1.5 score weight. The ⚡ bolt icon marks clustered matches: three or more patterns within a 10-line window, each receiving an additional ×1.5 density multiplier under the legacy scoring model.
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | .rubocop_todo.yml | 1 | # This configuration was generated by | COMMENT |
| LOW | benchmark/version_throughput/run.rb | 1 | # frozen_string_literal: true | COMMENT |
| LOW | benchmark/version_throughput/run.rb | 21 | # | COMMENT |
| LOW | benchmark/grape_on_rack/profile_api_calls.rb | 1 | #!/usr/bin/env ruby | COMMENT |
| LOW | spec/grape/api_concurrency_spec.rb | 1 | # frozen_string_literal: true | COMMENT |
| LOW | …ec/grape/validations/adversarial_nesting_depth_spec.rb | 1 | # frozen_string_literal: true | COMMENT |
| LOW | spec/grape/validations/frozen_validation_graph_spec.rb | 1 | # frozen_string_literal: true | COMMENT |
| LOW | lib/grape/router.rb | 81 | # regexp -- so once one route held a non-ASCII literal (`/café/:id`), | COMMENT |
| LOW | lib/grape/router.rb | 341 | # Grape::HTTP_SUPPORTED_METHODS. A route declared with any other verb | COMMENT |
| LOW | lib/grape/router.rb | 361 | # goes straight to the union rather than missing a lookup first. | COMMENT |
| LOW | lib/grape/mountable.rb | 1 | # frozen_string_literal: true | COMMENT |
| LOW | lib/grape/api.rb | 1 | # frozen_string_literal: true | COMMENT |
| LOW | lib/grape/api.rb | 41 | # rather than left to +delegate_missing_to+, which stays for the names | COMMENT |
| LOW | lib/grape/endpoint.rb | 81 | # @param new_settings [InheritableSetting] settings to determine the params, | COMMENT |
| LOW | lib/grape/endpoint.rb | 341 | callbacks: callbacks.each_value.all?(&:empty?) ? nil : callbacks.freeze, | COMMENT |
| LOW | lib/grape/endpoint.rb | 361 | # cache then started cold for the helpers, the route block and every DSL | COMMENT |
| LOW | lib/grape/request.rb | 181 | # Whether the request can have form params at all. Rack::Request#params is | COMMENT |
| LOW | lib/grape/request.rb | 221 | # | COMMENT |
| LOW | lib/grape/content_types.rb | 41 | COMMENT | |
| LOW | lib/grape/content_types.rb | 61 | # nil content type. Skips the split (and its allocation) when there are no | COMMENT |
| LOW | lib/grape/precompiled_json.rb | 1 | # frozen_string_literal: true | COMMENT |
| LOW | lib/grape/precompiled_json.rb | 21 | # rather than round-tripped: | COMMENT |
| LOW | lib/grape/middleware/versioner.rb | 1 | # frozen_string_literal: true | COMMENT |
| LOW | lib/grape/middleware/precomputed_content_types.rb | 1 | # frozen_string_literal: true | COMMENT |
| LOW | lib/grape/middleware/error.rb | 141 | body = html_content_type?(headers[Rack::CONTENT_TYPE]) ? Rack::Utils.escape_html(message) : message | COMMENT |
| LOW | lib/grape/middleware/error.rb | 201 | # The backtrace an error formatter is handed. Assembled only when the API | COMMENT |
| LOW | lib/grape/middleware/error.rb | 301 | COMMENT | |
| LOW | lib/grape/middleware/error.rb | 381 | # | COMMENT |
| LOW | lib/grape/middleware/formatter.rb | 21 | # Callers scrub the header first. | COMMENT |
| LOW | lib/grape/middleware/formatter.rb | 61 | # | COMMENT |
| LOW | lib/grape/middleware/formatter.rb | 341 | # the String its concatenation allocates. Tested with +empty?+ rather | COMMENT |
| LOW | lib/grape/middleware/versioner/path.rb | 1 | # frozen_string_literal: true | COMMENT |
| LOW | lib/grape/middleware/versioner/param.rb | 1 | # frozen_string_literal: true | COMMENT |
| LOW | lib/grape/middleware/versioner/accept_version_header.rb | 1 | # frozen_string_literal: true | COMMENT |
| LOW | lib/grape/middleware/versioner/header.rb | 1 | # frozen_string_literal: true | COMMENT |
| LOW | lib/grape/middleware/versioner/header.rb | 21 | # If version does not match this route, then a 406 is raised with | COMMENT |
| LOW | lib/grape/util/path_normalizer.rb | 1 | # frozen_string_literal: true | COMMENT |
| LOW | lib/grape/util/shadowed_rescue_handlers.rb | 1 | # frozen_string_literal: true | COMMENT |
| LOW | lib/grape/util/stackable_values.rb | 1 | # frozen_string_literal: true | COMMENT |
| LOW | lib/grape/util/media_type.rb | 1 | # frozen_string_literal: true | COMMENT |
| LOW | lib/grape/util/inheritable_setting.rb | 1 | # frozen_string_literal: true | COMMENT |
| LOW | lib/grape/util/inheritable_setting.rb | 81 | # Instantiate a new settings instance, with blank values. The fresh | COMMENT |
| LOW | lib/grape/util/inheritable_setting.rb | 241 | COMMENT | |
| LOW | lib/grape/util/inheritable_setting.rb | 541 | COMMENT | |
| LOW | lib/grape/util/inheritable_setting.rb | 561 | # The params-builder strategy set by +build_with+ (both the | COMMENT |
| LOW | lib/grape/util/scrub.rb | 1 | # frozen_string_literal: true | COMMENT |
| LOW | lib/grape/util/cache.rb | 1 | # frozen_string_literal: true | COMMENT |
| LOW | lib/grape/util/registry.rb | 21 | COMMENT | |
| LOW | lib/grape/util/lazy/value.rb | 1 | # frozen_string_literal: true | COMMENT |
| LOW | lib/grape/exceptions/error_response.rb | 1 | # frozen_string_literal: true | COMMENT |
| LOW | lib/grape/exceptions/halt.rb | 1 | # frozen_string_literal: true | COMMENT |
| LOW | lib/grape/validations/param_scope_tracker.rb | 1 | # frozen_string_literal: true | COMMENT |
| LOW | lib/grape/validations/validations_spec.rb | 1 | # frozen_string_literal: true | COMMENT |
| LOW | lib/grape/validations/params_scope.rb | 81 | attr_key(declared_param_attr.key) | COMMENT |
| LOW | lib/grape/validations/params_scope.rb | 221 | COMMENT | |
| LOW | lib/grape/validations/params_scope.rb | 261 | end | COMMENT |
| LOW | lib/grape/validations/params_scope.rb | 381 | def declare_optional_fields(fields, using) | COMMENT |
| LOW | lib/grape/validations/params_scope.rb | 481 | validate_coerce(spec, attrs) | COMMENT |
| LOW | lib/grape/validations/types.rb | 1 | # frozen_string_literal: true | COMMENT |
| LOW | lib/grape/validations/types.rb | 61 | # | COMMENT |
| 50 more matches not shown… | ||||
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | lib/grape/router.rb | 314 | def allowed_methods_route_for(input) | CODE |
| LOW | lib/grape/endpoint.rb | 321 | def instrument_run_validators(validators, request, &) | CODE |
| LOW | lib/grape/endpoint.rb | 490 | def formatter_middleware_options(format, content_types) | CODE |
| LOW⚡ | lib/grape/middleware/error.rb | 285 | def registered_rescue_handler(klass) | CODE |
| LOW⚡ | lib/grape/middleware/error.rb | 292 | def registered_rescue_handler_entry(klass) | CODE |
| LOW⚡ | lib/grape/middleware/error.rb | 297 | def rescue_handler_entry_from(handlers) | CODE |
| LOW | lib/grape/middleware/error.rb | 322 | def grape_exceptions_precedence_handler(klass, registered_entry) | CODE |
| LOW | lib/grape/middleware/error.rb | 333 | def rescue_handler_for_grape_exception(klass) | CODE |
| LOW | lib/grape/middleware/error.rb | 341 | def rescue_handler_for_any_class(klass) | CODE |
| LOW | lib/grape/middleware/formatter.rb | 189 | def instrument_format_response(env, formatter, &) | CODE |
| LOW | lib/grape/middleware/versioner/path.rb | 73 | def version_from_first_segment(path_info, slash_position) | CODE |
| LOW | lib/grape/middleware/versioner/path.rb | 84 | def version_from_only_segment(path_info) | CODE |
| LOW | lib/grape/util/inheritable_setting.rb | 359 | def add_grape_exceptions_rescue_handler(handler) | CODE |
| LOW | lib/grape/util/inheritable_setting.rb | 365 | def add_internal_grape_exceptions_rescue_handler(handler) | CODE |
| LOW | lib/grape/util/inheritable_setting.rb | 749 | def namespace_stackable_with_hash(key) | CODE |
| LOW | lib/grape/validations/validations_spec.rb | 99 | def check_incompatible_option_values(default, values, except_values) | CODE |
| LOW | lib/grape/validations/validations_spec.rb | 162 | def extract_value_and_message(opt) | CODE |
| LOW | lib/grape/validations/params_scope.rb | 350 | def require_required_and_optional_fields(context, using:, except: nil) | CODE |
| LOW | lib/grape/validations/validators/base.rb | 199 | def validate_element_attributes(element, array_errors) | CODE |
| LOW | …ape/validations/validators/contract_scope_validator.rb | 36 | def build_errors_from_messages(messages) | CODE |
| LOW | lib/grape/error_formatter/base.rb | 49 | def format_structured_message(_structured_message) | CODE |
| LOW | lib/grape/error_formatter/json.rb | 7 | def format_structured_message(structured_message) | CODE |
| LOW | lib/grape/error_formatter/jsonl.rb | 9 | def format_structured_message(structured_message) | CODE |
| LOW | lib/grape/api/instance.rb | 177 | def collect_route_config_per_pattern(all_routes) | CODE |
| LOW | lib/grape/api/instance.rb | 191 | def associate_allowed_methods_route(routes, setting) | CODE |
| LOW | lib/grape/dsl/helpers.rb | 71 | def inject_api_helpers_to_mod(mod, &block) | CODE |
| LOW | lib/grape/dsl/helpers.rb | 82 | def warn_on_endpoint_overrides(mod) | CODE |
| LOW | lib/grape/dsl/entity.rb | 115 | def entity_representation_for(entity_class, object, options) | CODE |
| LOW | lib/grape/dsl/parameters.rb | 223 | def redispatch_legacy_options(method_name, args, opts, &) | CODE |
| LOW | lib/grape/dsl/mounting.rb | 86 | def drop_endpoints_mounted_for(mounts) | CODE |
| LOW | lib/grape/dsl/mounting.rb | 135 | def evaluate_as_instance_with_configuration(block, lazy: false) | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM | spec/grape/util/registry_spec.rb | 4 | # Create a test class that includes the Registry module | COMMENT |
| MEDIUM | spec/grape/validations/validators/base_i18n_spec.rb | 41 | # Define the API while zh-CN is the active locale | COMMENT |
| MEDIUM | lib/grape/api.rb | 65 | # Initialize the instance variables on the remountable class, and the base_instance | COMMENT |
| MEDIUM | lib/grape/endpoint.rb | 80 | # Create a new endpoint. | COMMENT |
| MEDIUM | lib/grape/util/inheritable_setting.rb | 123 | # Create a point-in-time copy of this settings instance, with clones of | COMMENT |
| MEDIUM | lib/grape/validations/types/multiple_type_coercer.rb | 6 | # This class is intended for use with Grape endpoint parameters that | COMMENT |
| MEDIUM | lib/grape/dsl/routing.rb | 8 | # Define a root URL prefix for your entire API. | COMMENT |
| MEDIUM | lib/grape/dsl/routing.rb | 15 | # Create a scope without affecting the URL. | COMMENT |
| MEDIUM | lib/grape/dsl/parameters.rb | 150 | # Define a block of validations which should be applied if and only if | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM | lib/grape/api.rb | 89 | # configuration hash to the block which you can use to configure your | COMMENT |
| MEDIUM | lib/grape/dsl/parameters.rb | 117 | # # pass in a block, within which you can use any of the | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | lib/grape/dsl/request_response.rb | 123 | # entities once and then simply call `present` with the model. | COMMENT |
| MEDIUM | lib/grape/dsl/request_response.rb | 137 | # bubble up and utilize the entity provided on that `represent` call. | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM | lib/grape/validations/types/custom_type_coercer.rb | 18 | # ------------- | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | benchmark/version_throughput/run.rb | 19 | # Usage: | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | benchmark/grape_on_rack/app/acme_app.rb | 31 | # Check if the App wants us to pass the response along to others | COMMENT |