You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[$125] Send a message button on help site doesn't work #89309
Version Number: Reproducible in staging?: N Reproducible in production?: Y If this was caught during regression testing, add the test name, ID and link from BrowserStack: Email or phone of affected tester (no customers): Logs:https://stackoverflow.com/c/expensify/questions/4856 Expensify/Expensify Issue URL: Issue reported by:@joekaufmanexpensify Slack conversation (hyperlinked to channel name): #Expensify Bugs
The help site's Jekyll templates use a conditional in CONST.html that checks jekyll.environment == "production" to decide between the production URL (https://new.expensify.com) and the dev URL (https://dev.new.expensify.com:8082). However, the deployment workflow deployExpensifyHelp.yml:70-71 runs bundle exec jekyll build without setting JEKYLL_ENV=production. Jekyll defaults to "development", so the dev URL branch is always taken — even in the production deployment.
The "Send a message" button in default.html:114-118 uses the resulting CONCIERGE_CHAT_URL, which resolves to https://dev.new.expensify.com:8082/concierge.
What changes do you think we should make in order to solve the problem?
Set JEKYLL_ENV=production in both deployment workflows:
deployExpensifyHelp.yml (line 71): Change the build command to JEKYLL_ENV=production bundle exec jekyll build --source ./ --destination ./_site
deployNewHelp.yml (line 71): Same change — this workflow has the identical issue.
This ensures jekyll.environment evaluates to "production" and MAIN_SITE_URL is set to https://new.expensify.com.
What alternative solutions did you explore? (Optional)
An alternative would be to remove the conditional in CONST.html and always use the production URL, but keeping the environment-based toggle is useful for local development and PR preview builds.
Next Steps for Contributor+ team: Reply with @MelvinBot implement this to create a draft PR, @MelvinBot <your feedback> to refine this analysis, or explain why you are rejecting Melvin's proposal.
Please re-state the problem that we are trying to solve in this issue.
The "Send a message" button on the help.expensify.com site links to https://dev.new.expensify.com:8082/concierge instead of the production URL https://new.expensify.com/concierge, so clicking it takes users to a dev environment that doesn't load publicly.
What is the root cause of that problem?
The HelpDot site uses a Liquid template constant file to define the base URL, which conditionally sets MAIN_SITE_URL to the dev URL when jekyll.environment is not "production". The problem is that CONCIERGE_CHAT_URL — which is built from MAIN_SITE_URL and then used directly on the "Didn't find what you were looking for?" button in the default layout — is resolving to the dev URL. This means the Jekyll build that produced the currently deployed help site was not built with jekyll.environment=production, so the else branch ran and hardcoded the dev URL.
What changes do you think we should make in order to solve the problem?
The else branch in docs/_includes/CONST.html should be removed so that MAIN_SITE_URL always defaults to https://new.expensify.com regardless of the Jekyll environment. The dev URL override serves no real purpose for the public help site — if a developer is running the help site locally, having the concierge link point to production is perfectly acceptable and far safer than accidentally shipping the dev URL to production users. Removing the else branch entirely (leaving only the https://new.expensify.com assignment) eliminates the risk of the wrong URL being deployed again.
Please re-state the problem that we are trying to solve in this issue.
On help.expensify.com, the "Send a message" button shown under "Didn't find what you were looking for?" at the bottom of every help article links to https://dev.new.expensify.com:8082/concierge (a developer-only host that does not load for end users) instead of the production URL https://new.expensify.com/concierge. As a result, signed-in users never reach their Concierge DM and signed-out users never reach the sign-in flow.
What is the root cause of that problem?
The href of the "Send a message" button is rendered from a Liquid include that branches on Jekyll's environment, but the production deploy workflow never sets JEKYLL_ENV=production, so the development branch is always taken in the deployed site.
The button is defined in docs/_layouts/default.html and reads its href from the CONCIERGE_CHAT_URL capture defined in docs/_includes/CONST.html:
CONST.html selects between https://new.expensify.com and https://dev.new.expensify.com:8082 using {% if jekyll.environment == "production" %}. Per Jekyll's documented behavior, jekyll.environment falls back to the literal string "development" whenever the JEKYLL_ENV environment variable is unset at build time, so the else branch wins and MAIN_SITE_URL becomes https://dev.new.expensify.com:8082.
The Cloudflare Pages production deploy is driven by .github/workflows/deployExpensifyHelp.yml. That workflow invokes bundle exec jekyll build without exporting JEKYLL_ENV (neither at the job env: level nor at the step level), so the production build of help.expensify.com is silently produced as a development build:
Trigger: a user clicks "Send a message" on any article on help.expensify.com. Mechanism: the rendered href is the dev branch of the conditional because the production build was not tagged as such. Impact: navigation lands on dev.new.expensify.com:8082, which is not reachable from outside Expensify's dev environment, so the support entry point is broken.
This also explains why the issue reproduces in production but not in staging in the way the reporter framed it — staging here is the live site, and there is no separate prod-vs-staging gate on JEKYLL_ENV; both deploys behave identically (development), but only the prod help site is what end users hit.
What changes do you think we should make in order to solve the problem?
In .github/workflows/deployExpensifyHelp.yml, set JEKYLL_ENV: production for the "Build Jekyll site" step (or at the job level) so that jekyll.environment evaluates to "production" during the build that ships to help.expensify.com.
Re-run the deploy workflow on main so the rebuilt site contains the corrected href, then verify by viewing-source on any deployed article that the "Send a message" anchor resolves to https://new.expensify.com/concierge.
Leave docs/_includes/CONST.html and docs/_layouts/default.html as-is; the Liquid conditional is correct, only the build environment was missing.
Optional hardening, in the same PR: invert the default in CONST.html so that production is the safe default and jekyll.environment == "development" is the explicit opt-in for local builds. This way a future omission of JEKYLL_ENV cannot regress live users; local bundle exec jekyll serve already sets JEKYLL_ENV=development automatically.
Scope boundaries: the only repo-level change required is in .github/workflows/deployExpensifyHelp.yml; the optional hardening adds a one-line edit to docs/_includes/CONST.html. No application code (src/**), no Mobile-Expensify code, no native code, and no other workflow files are touched. The sister workflow .github/workflows/deployNewHelp.yml (which deploys newhelp.expensify.com) should receive the same JEKYLL_ENV: production treatment in this PR for consistency, since it builds from the same docs/ source. No Jekyll plugins, layouts, redirect rules, or article content are affected.
What alternative solutions did you explore? (Optional)
Hardcoding https://new.expensify.com/concierge in docs/_layouts/default.html and deleting the conditional. Rejected — local Jekyll dev would then lose the convenience of pointing the button at the local dev server, and the existing MAIN_SITE_URL capture is reused elsewhere (the same constants file, intended for additional URLs over time). The right fix is to make the existing branch evaluate correctly in CI, not to delete it.
Detecting the deploy target via site.url (https://help.expensify.com) inside CONST.html instead of jekyll.environment. Rejected — site.url is set in _config.yml and is the same string in PR previews and production, so it cannot distinguish a user-facing build from a local one.
Introducing a separate _config.production.yml overlay. Workable but heavier than necessary; JEKYLL_ENV is the idiomatic Jekyll lever for exactly this branch and adding a second config file is more surface area than the bug warrants.
Please re-state the problem that we are trying to solve in this issue.
The help site footer’s “Send a message” button can generate a link to https://dev.new.expensify.com:8082/concierge, so users clicking it are sent to a local/dev NewDot URL instead of the public Concierge route.
What is the root cause of that problem?
docs/_layouts/default.html includes docs/_includes/CONST.html and uses {{ CONCIERGE_CHAT_URL }} for the footer CTA.
In docs/_includes/CONST.html, MAIN_SITE_URL depends on jekyll.environment:
That command does not set JEKYLL_ENV=production, so Jekyll evaluates jekyll.environment as the default non-production environment and the generated static footer link uses the dev URL.
The app route itself is not the broken layer. src/ROUTES.ts defines ROUTES.CONCIERGE = 'concierge', src/libs/Navigation/linkingConfig/config.ts maps SCREENS.CONCIERGE to that route, and src/pages/ConciergePage.tsx handles /concierge by routing authenticated users to Concierge or unauthenticated users through sign-in.
What changes do you think we should make in order to solve the problem?
Set the Jekyll environment explicitly in .github/workflows/deployExpensifyHelp.yml when building the deployed help site:
This keeps docs/_includes/CONST.html centralized and preserves its intended local development behavior, while ensuring deployed help builds generate:
href="https://new.expensify.com/concierge"
What alternative solutions did you explore? (Optional)
Hardcoding CONCIERGE_CHAT_URL in docs/_includes/CONST.html would fix this one CTA, but it would only patch the symptom and remove the existing local/dev behavior from the Liquid constants. The deeper issue is that the deployed help workflow is building production static HTML without telling Jekyll it is a production build.
⚠️@aswin-s Your proposal is a duplicate of an already existing proposal and has been automatically withdrawn to prevent spam. Please review the existing proposals before submitting a new one.
The help.expensify.com footer button is rendered from docs/_layouts/default.html, where the “Send a message” link uses CONCIERGE_CHAT_URL from docs/_includes/CONST.html:
CONCIERGE_CHAT_URL is built from MAIN_SITE_URL, and MAIN_SITE_URL only points to https://new.expensify.com when jekyll.environment == "production". Otherwise, it points to https://dev.new.expensify.com:8082:
The production help-site deployment builds docs/ with bundle exec jekyll build but does not set JEKYLL_ENV=production, so Jekyll uses its default development environment and the deployed HTML gets the dev Concierge URL:
What changes do you think we should make in order to solve the problem?
Set JEKYLL_ENV: production on the Build Jekyll site step in .github/workflows/deployExpensifyHelp.yml.
This keeps the existing CONST.html environment split intact for local docs development, while making the Cloudflare Pages build for help.expensify.com render the production Concierge URL.
Required changes:
Add JEKYLL_ENV: production to the Jekyll build step in .github/workflows/deployExpensifyHelp.yml.
Re-run the deploy workflow so the generated site contains https://new.expensify.com/concierge.
Tests that should be added:
No automated test is necessary for this workflow-only configuration change.
Validate by running the docs build with JEKYLL_ENV=production and confirming the generated Send a message anchor points to https://new.expensify.com/concierge.
Updating .github/workflows/deployNewHelp.yml is not needed for this issue. That workflow builds the separate help/ directory, while the broken CONCIERGE_CHAT_URL include and the affected “Send a message” button are only in docs/.
Removing the development branch from docs/_includes/CONST.html would also prevent the wrong URL from shipping, but it changes the local docs behavior unnecessarily. The root cause is the missing production Jekyll environment in the deploy workflow.
What alternative solutions did you explore? (Optional)
This issue has not been updated in over 15 days. @puneetlath, @brunovjk eroding to Monthly issue.
P.S. Is everyone reading this sure this is really a near-term priority? Be brave: if you disagree, go ahead and close it out. If someone disagrees, they'll reopen it, and if they don't: one less thing to do!
Activity
MelvinBot commentedon Apr 30, 2026
Proposal
What is the root cause of that problem?
The help site's Jekyll templates use a conditional in
CONST.htmlthat checksjekyll.environment == "production"to decide between the production URL (https://new.expensify.com) and the dev URL (https://dev.new.expensify.com:8082). However, the deployment workflowdeployExpensifyHelp.yml:70-71runsbundle exec jekyll buildwithout settingJEKYLL_ENV=production. Jekyll defaults to"development", so the dev URL branch is always taken — even in the production deployment.The "Send a message" button in
default.html:114-118uses the resultingCONCIERGE_CHAT_URL, which resolves tohttps://dev.new.expensify.com:8082/concierge.What changes do you think we should make in order to solve the problem?
Set
JEKYLL_ENV=productionin both deployment workflows:deployExpensifyHelp.yml(line 71): Change the build command toJEKYLL_ENV=production bundle exec jekyll build --source ./ --destination ./_sitedeployNewHelp.yml(line 71): Same change — this workflow has the identical issue.This ensures
jekyll.environmentevaluates to"production"andMAIN_SITE_URLis set tohttps://new.expensify.com.What alternative solutions did you explore? (Optional)
An alternative would be to remove the conditional in
CONST.htmland always use the production URL, but keeping the environment-based toggle is useful for local development and PR preview builds.Next Steps for Contributor+ team: Reply with
@MelvinBot implement thisto create a draft PR,@MelvinBot <your feedback>to refine this analysis, or explain why you are rejecting Melvin's proposal.melvin-bot commentedon Apr 30, 2026
Triggered auto assignment to Contributor-plus team member for initial proposal review - @brunovjk (
External)MobileMage commentedon Apr 30, 2026
Proposal
Please re-state the problem that we are trying to solve in this issue.
The "Send a message" button on the help.expensify.com site links to
https://dev.new.expensify.com:8082/conciergeinstead of the production URLhttps://new.expensify.com/concierge, so clicking it takes users to a dev environment that doesn't load publicly.What is the root cause of that problem?
The HelpDot site uses a Liquid template constant file to define the base URL, which conditionally sets
MAIN_SITE_URLto the dev URL whenjekyll.environmentis not"production". The problem is thatCONCIERGE_CHAT_URL— which is built fromMAIN_SITE_URLand then used directly on the "Didn't find what you were looking for?" button in the default layout — is resolving to the dev URL. This means the Jekyll build that produced the currently deployed help site was not built withjekyll.environment=production, so theelsebranch ran and hardcoded the dev URL.App/docs/_includes/CONST.html
Lines 1 to 7 in 3210e49
What changes do you think we should make in order to solve the problem?
The
elsebranch indocs/_includes/CONST.htmlshould be removed so thatMAIN_SITE_URLalways defaults tohttps://new.expensify.comregardless of the Jekyll environment. The dev URL override serves no real purpose for the public help site — if a developer is running the help site locally, having the concierge link point to production is perfectly acceptable and far safer than accidentally shipping the dev URL to production users. Removing theelsebranch entirely (leaving only thehttps://new.expensify.comassignment) eliminates the risk of the wrong URL being deployed again.App/docs/_layouts/default.html
Lines 112 to 116 in 3210e49
What alternative solutions did you explore? (Optional)
N/A
[-]Send a message button on help site doesn't work[/-][+][$250] Send a message button on help site doesn't work[/+]melvin-bot commentedon Apr 30, 2026
Job added to Upwork: https://www.upwork.com/jobs/~022049957471456145777
KJ21-ENG commentedon Apr 30, 2026
Proposal
Please re-state the problem that we are trying to solve in this issue.
On
help.expensify.com, the "Send a message" button shown under "Didn't find what you were looking for?" at the bottom of every help article links tohttps://dev.new.expensify.com:8082/concierge(a developer-only host that does not load for end users) instead of the production URLhttps://new.expensify.com/concierge. As a result, signed-in users never reach their Concierge DM and signed-out users never reach the sign-in flow.What is the root cause of that problem?
The href of the "Send a message" button is rendered from a Liquid include that branches on Jekyll's environment, but the production deploy workflow never sets
JEKYLL_ENV=production, so the development branch is always taken in the deployed site.The button is defined in
docs/_layouts/default.htmland reads its href from theCONCIERGE_CHAT_URLcapture defined indocs/_includes/CONST.html:App/docs/_layouts/default.html
Lines 109 to 119 in 3210e49
https://github.com/Expensify/App/blob/3210e497eb743d6417e13a9e3fbf9a4e13b2c044/docs/_includes/CONST.html#L1-L8
CONST.htmlselects betweenhttps://new.expensify.comandhttps://dev.new.expensify.com:8082using{% if jekyll.environment == "production" %}. Per Jekyll's documented behavior,jekyll.environmentfalls back to the literal string"development"whenever theJEKYLL_ENVenvironment variable is unset at build time, so theelsebranch wins andMAIN_SITE_URLbecomeshttps://dev.new.expensify.com:8082.The Cloudflare Pages production deploy is driven by
.github/workflows/deployExpensifyHelp.yml. That workflow invokesbundle exec jekyll buildwithout exportingJEKYLL_ENV(neither at the jobenv:level nor at the step level), so the production build ofhelp.expensify.comis silently produced as a development build:App/.github/workflows/deployExpensifyHelp.yml
Lines 29 to 73 in 3210e49
Trigger: a user clicks "Send a message" on any article on
help.expensify.com. Mechanism: the rendered href is the dev branch of the conditional because the production build was not tagged as such. Impact: navigation lands ondev.new.expensify.com:8082, which is not reachable from outside Expensify's dev environment, so the support entry point is broken.This also explains why the issue reproduces in production but not in staging in the way the reporter framed it — staging here is the live site, and there is no separate prod-vs-staging gate on
JEKYLL_ENV; both deploys behave identically (development), but only the prod help site is what end users hit.What changes do you think we should make in order to solve the problem?
.github/workflows/deployExpensifyHelp.yml, setJEKYLL_ENV: productionfor the "Build Jekyll site" step (or at the job level) so thatjekyll.environmentevaluates to"production"during the build that ships tohelp.expensify.com.mainso the rebuilt site contains the corrected href, then verify by viewing-source on any deployed article that the "Send a message" anchor resolves tohttps://new.expensify.com/concierge.docs/_includes/CONST.htmlanddocs/_layouts/default.htmlas-is; the Liquid conditional is correct, only the build environment was missing.CONST.htmlso that production is the safe default andjekyll.environment == "development"is the explicit opt-in for local builds. This way a future omission ofJEKYLL_ENVcannot regress live users; localbundle exec jekyll servealready setsJEKYLL_ENV=developmentautomatically.Scope boundaries: the only repo-level change required is in
.github/workflows/deployExpensifyHelp.yml; the optional hardening adds a one-line edit todocs/_includes/CONST.html. No application code (src/**), no Mobile-Expensify code, no native code, and no other workflow files are touched. The sister workflow.github/workflows/deployNewHelp.yml(which deploysnewhelp.expensify.com) should receive the sameJEKYLL_ENV: productiontreatment in this PR for consistency, since it builds from the samedocs/source. No Jekyll plugins, layouts, redirect rules, or article content are affected.What alternative solutions did you explore? (Optional)
https://new.expensify.com/conciergeindocs/_layouts/default.htmland deleting the conditional. Rejected — local Jekyll dev would then lose the convenience of pointing the button at the local dev server, and the existingMAIN_SITE_URLcapture is reused elsewhere (the same constants file, intended for additional URLs over time). The right fix is to make the existing branch evaluate correctly in CI, not to delete it.site.url(https://help.expensify.com) insideCONST.htmlinstead ofjekyll.environment. Rejected —site.urlis set in_config.ymland is the same string in PR previews and production, so it cannot distinguish a user-facing build from a local one._config.production.ymloverlay. Workable but heavier than necessary;JEKYLL_ENVis the idiomatic Jekyll lever for exactly this branch and adding a second config file is more surface area than the bug warrants.aswin-s commentedon Apr 30, 2026
Proposal
Please re-state the problem that we are trying to solve in this issue.
The help site footer’s “Send a message” button can generate a link to
https://dev.new.expensify.com:8082/concierge, so users clicking it are sent to a local/dev NewDot URL instead of the public Concierge route.What is the root cause of that problem?
docs/_layouts/default.htmlincludesdocs/_includes/CONST.htmland uses{{ CONCIERGE_CHAT_URL }}for the footer CTA.In
docs/_includes/CONST.html,MAIN_SITE_URLdepends onjekyll.environment:{% if jekyll.environment == "production" %} {% assign MAIN_SITE_URL = "https://new.expensify.com" %} {% else %} {% assign MAIN_SITE_URL = "https://dev.new.expensify.com:8082" %} {% endif %}However,
.github/workflows/deployExpensifyHelp.ymlbuilds the production help site with:That command does not set
JEKYLL_ENV=production, so Jekyll evaluatesjekyll.environmentas the default non-production environment and the generated static footer link uses the dev URL.The app route itself is not the broken layer.
src/ROUTES.tsdefinesROUTES.CONCIERGE = 'concierge',src/libs/Navigation/linkingConfig/config.tsmapsSCREENS.CONCIERGEto that route, andsrc/pages/ConciergePage.tsxhandles/conciergeby routing authenticated users to Concierge or unauthenticated users through sign-in.What changes do you think we should make in order to solve the problem?
Set the Jekyll environment explicitly in
.github/workflows/deployExpensifyHelp.ymlwhen building the deployed help site:This keeps
docs/_includes/CONST.htmlcentralized and preserves its intended local development behavior, while ensuring deployed help builds generate:What alternative solutions did you explore? (Optional)
Hardcoding
CONCIERGE_CHAT_URLindocs/_includes/CONST.htmlwould fix this one CTA, but it would only patch the symptom and remove the existing local/dev behavior from the Liquid constants. The deeper issue is that the deployed help workflow is building production static HTML without telling Jekyll it is a production build.github-actions commentedon Apr 30, 2026
nabi-ebrahimi commentedon Apr 30, 2026
Proposal
What is the root cause of that problem?
The
help.expensify.comfooter button is rendered fromdocs/_layouts/default.html, where the “Send a message” link usesCONCIERGE_CHAT_URLfromdocs/_includes/CONST.html:App/docs/_layouts/default.html
Lines 109 to 118 in 3210e49
CONCIERGE_CHAT_URLis built fromMAIN_SITE_URL, andMAIN_SITE_URLonly points tohttps://new.expensify.comwhenjekyll.environment == "production". Otherwise, it points tohttps://dev.new.expensify.com:8082:App/docs/_includes/CONST.html
Lines 1 to 7 in 3210e49
The production help-site deployment builds
docs/withbundle exec jekyll buildbut does not setJEKYLL_ENV=production, so Jekyll uses its default development environment and the deployed HTML gets the dev Concierge URL:App/.github/workflows/deployExpensifyHelp.yml
Lines 70 to 72 in 3210e49
What changes do you think we should make in order to solve the problem?
Set
JEKYLL_ENV: productionon theBuild Jekyll sitestep in.github/workflows/deployExpensifyHelp.yml.This keeps the existing
CONST.htmlenvironment split intact for local docs development, while making the Cloudflare Pages build forhelp.expensify.comrender the production Concierge URL.Required changes:
JEKYLL_ENV: productionto the Jekyll build step in.github/workflows/deployExpensifyHelp.yml.https://new.expensify.com/concierge.Tests that should be added:
JEKYLL_ENV=productionand confirming the generatedSend a messageanchor points tohttps://new.expensify.com/concierge.Updating
.github/workflows/deployNewHelp.ymlis not needed for this issue. That workflow builds the separatehelp/directory, while the brokenCONCIERGE_CHAT_URLinclude and the affected “Send a message” button are only indocs/.Removing the development branch from
docs/_includes/CONST.htmlwould also prevent the wrong URL from shipping, but it changes the local docs behavior unnecessarily. The root cause is the missing production Jekyll environment in the deploy workflow.What alternative solutions did you explore? (Optional)
30 remaining items
brunovjk commentedon May 11, 2026
PR is ready for review @puneetlath
brunovjk commentedon May 22, 2026
Same as above.
brunovjk commentedon May 29, 2026
Update: PR still under review.
melvin-bot commentedon Jun 3, 2026
This issue has not been updated in over 15 days. @puneetlath, @brunovjk eroding to Monthly issue.
P.S. Is everyone reading this sure this is really a near-term priority? Be brave: if you disagree, go ahead and close it out. If someone disagrees, they'll reopen it, and if they don't: one less thing to do!
brunovjk commentedon Jun 17, 2026
Update: PR still under review.
puneetlath commentedon Jun 19, 2026
This is no longer needed. It was addressed here: #91119
m-natarajan commentedon Jun 25, 2026
@puneetlath This issue is still reproducible, Can you please have a look.
Recording.3089.mp4
puneetlath commentedon Jul 8, 2026
@m-natarajan seems like a new issue. Can you open a new GH issue for it?
m-natarajan commentedon Jul 8, 2026
@puneetlath New GH created for this here