Skip to content

fix: reject empty/null input to match serverless platform behavior#302

Open
deanq wants to merge 9 commits intomainfrom
deanq/ae-2744-payload-validation-parity
Open

fix: reject empty/null input to match serverless platform behavior#302
deanq wants to merge 9 commits intomainfrom
deanq/ae-2744-payload-validation-parity

Conversation

@deanq
Copy link
Copy Markdown
Member

@deanq deanq commented Apr 9, 2026

Summary

  • Dev server (flash run) QB routes now reject {"input": {}} with 422, matching RunPod platform behavior which silently times out on empty input
  • Deployed handler templates (handler_generator.py) return error dict for empty/null input (defense-in-depth)
  • create_deployed_handler replaces silent None-to-empty-dict fallback with explicit rejection
  • Fixes pre-existing bug where saveEndpoint included a fresh template when updating an endpoint with an existing templateId, causing spurious releases

Test plan

  • Verify flash run rejects {"input": {}} with 422 and actionable error message
  • Verify flash run accepts {"input": {"param_name": null}} for optional params
  • Verify flash build generates handlers with empty-input validation guard
  • Verify make quality-check passes (2512 tests, 85.59% coverage)

Resolves AE-2744

@promptless
Copy link
Copy Markdown

promptless bot commented Apr 9, 2026

Promptless prepared a documentation update related to this change.

Triggered by runpod/flash PR #302

Added documentation for the new empty input validation behavior — a warning block explaining that the input object must contain at least one field, HTTP 422 status code in the response codes table, and a troubleshooting section for empty/null input errors.

Review at https://app.gopromptless.ai/suggestions/734d43e8-9534-4cab-80cb-76bca28b3d58

@deanq deanq changed the title fix: reject empty/null input to match RunPod platform behavior (AE-2744) fix: reject empty/null input to match serverless platform behavior Apr 9, 2026
@deanq deanq force-pushed the deanq/ae-2744-payload-validation-parity branch from d5ce86c to 0017c6c Compare April 9, 2026 21:37
deanq added 7 commits April 9, 2026 15:30
Three-task TDD plan: (1) call_with_body validation in dev server,
(2) deployed handler template validation, (3) create_deployed_handler
rejection. Each task follows red-green-commit cycle.
call_with_body now checks model_fields_set and returns 422 when the
user sends {"input": {}}. This matches RunPod platform behavior,
which silently times out on empty input instead of dispatching the job.
Both function and class handler templates now return an error dict
when job input is empty or null. Defense-in-depth: the RunPod platform
typically blocks empty-input jobs, but this protects against platform
behavior changes and direct handler testing.
Standardize on "Empty or null input." across all validation points
for consistent developer experience when debugging across dev server
and deployed endpoints.
Replace silent None-to-empty-dict fallback with explicit rejection.
Returns {success: false, error: ...} for empty/null input, consistent
with the dev server and handler template validation.
… exists

When updating an endpoint that already has a templateId, the
saveEndpoint payload included a fresh template object because
_payload_exclude was called on new_config (templateId=None) instead
of using the resolved templateId from the existing endpoint. This
caused the API to create a new template with empty env, triggering
a spurious release.

Also removes superpowers docs that were incorrectly committed to
the repo (they belong in flash-project/docs).
@deanq deanq force-pushed the deanq/ae-2744-payload-validation-parity branch from 0017c6c to d56737d Compare April 9, 2026 22:30
@deanq deanq requested a review from Copilot April 10, 2026 08:36
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR tightens input validation across the dev server (flash run) and deployed handler generation to reject empty/null input, aligning behavior with the RunPod serverless platform, and fixes an endpoint update path that could unintentionally trigger new template releases.

Changes:

  • Reject empty/null job input for QB handlers (dev server + deployed handler factory) with a clear 422-style error message.
  • Add empty-input guards to generated deployed handler templates (defense-in-depth) and update unit tests accordingly.
  • Adjust ServerlessResource.update() payload construction to avoid sending a fresh template when an existing templateId should be reused, preventing spurious releases.

Reviewed changes

Copilot reviewed 11 out of 11 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
tests/unit/test_p2_gaps.py Updates template assertions to match new empty-input guard behavior.
tests/unit/runtime/test_generic_handler.py Updates deployed handler tests to expect rejection for missing/None input.
tests/unit/runtime/test_generic_handler_extended.py Adds/updates coverage around empty/null/missing input rejection.
tests/unit/runtime/test_deployed_handler.py Updates deployed handler behavior expectations and test call shapes.
tests/unit/resources/test_serverless.py Adds regression tests ensuring updates reuse existing templateId rather than sending a fresh template.
tests/unit/cli/commands/test_run_server_helpers.py Adds tests for call_with_body rejecting empty Pydantic models while allowing explicit nulls.
tests/unit/cli/commands/build_utils/test_handler_generator.py Adds tests asserting generated handler files include empty-input guards.
src/runpod_flash/runtime/generic_handler.py Changes create_deployed_handler to reject empty/null input explicitly and return actionable errors.
src/runpod_flash/core/resources/serverless.py Changes update payload exclusion logic to avoid sending template when an existing templateId is available.
src/runpod_flash/cli/commands/build_utils/handler_generator.py Updates deployed handler templates to guard against empty/null input.
src/runpod_flash/cli/commands/_run_server_helpers.py Adds dev-server-side empty-input validation in call_with_body via Pydantic model_fields_set.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

…emplateId override

Handler templates now use explicit None/empty-dict/non-dict checks
instead of `or {}` which could misclassify falsy non-dict inputs.
templateId injection in update() now only applies when new_config
does not explicitly set its own templateId, preserving intentional
template switches.
@deanq deanq requested review from KAJdev and runpod-Henrik April 10, 2026 19:29
- Add "success": False to all handler template error dicts for
  consistency with create_deployed_handler
- Document why create_handler intentionally accepts None input
- Narrow call_with_body docstring to clarify Pydantic-only validation
- Defensive copy of _payload_exclude() return value
- Add debug log when template excluded from saveEndpoint payload
- Add tests for empty plain dict body and falsy non-dict inputs
- Fix stale test docstrings
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants