firebase-functions icon indicating copy to clipboard operation
firebase-functions copied to clipboard

onSchedule() with string parameter creates Cloud Scheduler jobs with incorrect v1 URLs instead of v2 Cloud Run URLs

Open ebeloded opened this issue 2 months ago • 2 comments

[REQUIRED] Environment info

firebase-functions: 6.4.0
firebase-tools: 14.16.0
Platform: macOS (Darwin 25.0.0)

[REQUIRED] Test case

import { onSchedule } from 'firebase-functions/v2/scheduler'

// This FAILS - creates scheduler with wrong URL format
export const failingScheduler = onSchedule(
  'every 1 minutes',
  async () => {
    console.log('This function gets PERMISSION_DENIED')
  }
)

// This WORKS - creates scheduler with correct URL
export const workingScheduler = onSchedule(
  {
    schedule: 'every 1 minutes', 
    timeZone: 'America/Los_Angeles',
  },
  async () => {
    console.log('This function works correctly')
  }
)

[REQUIRED] Steps to reproduce

  1. Create a v2 scheduled function using the string parameter syntax
  2. Deploy with firebase deploy --only functions
  3. Check Cloud Scheduler console
  4. Observe the scheduler job has URL: https://us-central1-PROJECT.cloudfunctions.net/FUNCTION_NAME (v1 format)
  5. Function execution fails with PERMISSION_DENIED

[REQUIRED] Expected behavior

Both syntaxes should create Cloud Scheduler jobs with the correct v2 Cloud Run URLs (format: https://FUNCTION_NAME-HASH-uc.a.run.app/)

[REQUIRED] Actual behavior

When using the string parameter syntax, Cloud Scheduler jobs are created with v1 function URLs that don't exist, causing PERMISSION_DENIED errors.

Cloud Scheduler shows:

  • Functions with string syntax: URL points to cloudfunctions.net (v1) - FAILS
  • Functions with object syntax: URL points to run.app (v2) - WORKS

Analysis

The TypeScript types allow both signatures:

onSchedule(schedule: string, handler: Function)
onSchedule(options: ScheduleOptions, handler: Function)

However, only the object syntax properly configures the Cloud Scheduler job with the correct Cloud Run URL. This is a critical bug because:

  1. The types suggest both are valid
  2. The deployment succeeds without warnings
  3. The error only appears at runtime when scheduler tries to invoke the function
  4. The error message (PERMISSION_DENIED) doesn't indicate the root cause is a URL mismatch

Workaround

Always use the object syntax with explicit schedule and timeZone properties:

onSchedule({
  schedule: 'every 1 minutes',
  timeZone: 'America/Los_Angeles',
}, handler)

Related Issues

This appears related to:

  • #1425 (PERMISSION_DENIED errors)
  • #1447 (Cloud Function V2 not creating deterministic Function URL)
  • #1293 (V2 scheduled functions deployment issues)

ebeloded avatar Sep 25 '25 19:09 ebeloded

I couldn't figure out how to label this issue, so I've labeled it for a human to triage. Hang tight.

google-oss-bot avatar Sep 25 '25 19:09 google-oss-bot

Hi! Thanks for raising this. It's been received and we will provide updates when available.

cabljac avatar Sep 29 '25 16:09 cabljac