Webhook Fails for Telegram Bot – APP_URL Trailing Semicolon Causes 404 (Despite Not Being in ENV)/RAILWAY VARIABLE

valescaray
HOBBY

18 days ago

Description of the Issue:

I'm deploying a Telegram bot using Node.js and the Telegraf library on Railway. The bot works fine locally and also when deployed to Render, but fails on Railway when trying to set a webhook.

The failure seems to be caused by a semicolon (;) being appended automatically to the webhook URL constructed using process.env.APP_URL, even though the environment variable in Railway does not contain a semicolon in the value.

Error Message and Description:

When setting the webhook via:

CopyEdit

await bot.telegram.setWebhook(`${process.env.APP_URL}/webhook`);

I get this error:

CopyEdit

TelegramError: 404: Not Found payload: { url: 'https://bot-test-production-1293.up.railway.app/webhook'; }

Note the semicolon at the end of the webhook URL:

'https://bot-test-production-1293.up.railway.app/webhook';

This is not present in my variable value. It breaks the Telegram API call.

I also tested this via manual curl:

curl -X POST https://api.telegram.org/bot<my_token>/setWebhook \ -H "Content-Type: application/json" \ -d '{"url": "https://bot-test-production-1293.up.railway.app/webhook"} Telegram returned {"ok":true}, proving the endpoint is correct and reachable when the semicolon is not present.

Build/Deploy Logs:

There’s no error during build. Error occurs during runtime when the webhook is being set:

Failed to launch bot: TelegramError: 404: Not Found payload: { url: 'https://bot-test-production-1293.up.railway.app/webhook'; }

This shows the invalid semicolon.

Code Repository (If applicable):

[Private repo] – But I can provide a stripped-down minimal version if needed. The important code snippet:

const WEBHOOK_PATH = "/webhook"; const WEBHOOK_URL = $`{process.env.APP_URL}${WEBHOOK_PATH}`; await bot.telegram.setWebhook(WEBHOOK_URL);

Conclusion and Request:

I believe Railway is injecting a semicolon when interpolating or exporting APP_URL, even though it’s not in the variable editor. This causes third-party API integrations (like Telegram webhooks) to break silently.

Please help confirm:

Is this a known issue?

Can it be fixed or worked around?

Is there an internal sanitization step I need to disable?

This issue only happens on Railway and cost me a lot of debugging time. Happy to assist with more info or test cases.

$10 Bounty

7 Replies

18 days ago

This thread has been marked as public for community involvement, as it does not contain any sensitive or personal information. Any further activity in this thread will be visible to everyone.

Status changed to Open brody 18 days ago


18 days ago

 { url: 'https://bot-test-production-1293.up.railway.app/webhook'; }

if you see, the ; is outside the url string value. The value probably doesn't have a ; and it's only shown in the error message that is being printed. You can double check by doing console.log(WEBHOOK_URL) and seeing what it is printing.

It looks the error is actually complaining about NOT_FOUND which means the telegram endpoint you are hitting is unable to be found. Can you double check the token you are setting when initiating bot.telegram?


pksunkara

{ url: 'https://bot-test-production-1293.up.railway.app/webhook'; }if you see, the ; is outside the url string value. The value probably doesn't have a ; and it's only shown in the error message that is being printed. You can double check by doing console.log(WEBHOOK_URL) and seeing what it is printing.It looks the error is actually complaining about NOT_FOUND which means the telegram endpoint you are hitting is unable to be found. Can you double check the token you are setting when initiating bot.telegram?

valescaray
HOBBY

18 days ago

Thank you for your response.

Regarding console.log(WEBHOOK_URL): I’ve already tested this, and the returned URL does not include a semicolon.

As for bot.telegram token: I'm confident the Telegram token is correct. I’ve cross-checked it multiple times, and it works perfectly in other environments — both when deployed locally and using the WSL terminal and when hosted on another site.


18 days ago

Then the only other possibility on why the code fails but the curl command passes is that the server (or railway endpoint) might not be ready yet on Railway when the setWebhook function is being run. Maybe add a few-second delay and see if it works?


pksunkara

Then the only other possibility on why the code fails but the curl command passes is that the server (or railway endpoint) might not be ready yet on Railway when the setWebhook function is being run. Maybe add a few-second delay and see if it works?

valescaray
HOBBY

18 days ago

Thank you for your response.

I just added the following:

setTimeout(async () => { try { await bot.telegram.setWebhook(WEBHOOK_URL); console.log(" Webhook set to:", WEBHOOK_URL); } catch (err) { console.error(" Failed to set webhook:", err); } }, 5000); // Wait 5 seconds before setting the webhook

Despite placing setWebhook after app.listen() to ensure the server is fully loaded before it's called, I’m still encountering the same error.


valescaray

Thank you for your response.I just added the following:jssetTimeout(async () => { try { await bot.telegram.setWebhook(WEBHOOK_URL); console.log(" Webhook set to:", WEBHOOK_URL); } catch (err) { console.error(" Failed to set webhook:", err); } }, 5000); // Wait 5 seconds before setting the webhookDespite placing setWebhook after app.listen() to ensure the server is fully loaded before it's called, I’m still encountering the same error.

sim
FREETop 1% Contributor

18 days ago

Try have the webhook callback be registered before you set it? https://telegraf.js.org/classes/Telegraf-1.html#webhookCallbac an app.use(bot.webhookCallback('/webhook'));


sim

Try have the webhook callback be registered before you set it? https://telegraf.js.org/classes/Telegraf-1.html#webhookCallbac an app.use(bot.webhookCallback('/webhook'));

valescaray
HOBBY

17 days ago

Thank you for your response.

i actually did: app.use(bot.webhookCallback(WEBHOOK_PATH));


valescaray

Thank you for your response.i actually did: app.use(bot.webhookCallback(WEBHOOK_PATH));

valescaray
HOBBY

17 days ago

Any advice on how i can get railway team to look into it. I have not gotten any feedback from them. I strongly believe its a fault from there end .